All opinions expressed are those of the authors and not necessarily those of OSNews.com, our sponsors, or our affiliates.
  Add to My Yahoo!  Subscribe with Bloglines  Subscribe in NewsGator Online

published by noreply@blogger.com (Peter Hankiewicz) on 2017-10-04 00:00:00 in the "angular" category

Why I'm doing this?

I often see that people use AngularJS and Angular names interchangeably. It's an obvious mistake for someone familiar with the front-end programming.

If you don't believe me (why would you?) just go to the Angular team repository or Wikipedia (Angular and AngularJS).

AngularJS (1.X)

AngularJS is a popular open-source JavaScript framework created by Mi?ko Hevery released in 2010 that was subsequently taken over by Google. It's not the same thing as Angular. The latest stable version of the framework is 1.6.6.

Angular (2+)

Angular is an open-source TypeScript-based framework created by Google from scratch. It's been totally rewritten and not compatible with AngularJS. The latest stable version of the framework is 4.4.4. They started from version 2 to avoid even more confusion.

Summary

I feel I have made the world better. Go now and correct everyone (it's such fun)!


Comments

published by noreply@blogger.com (Elizabeth Garrett Christensen on 2016-12-23 16:30:00 in the "AngularJS" category

Carjojo?s site makes use of some of the best tools on the market today for accessing and displaying data. Carjojo is a car buying application that takes data about car pricing, dealer incentives, and rebate programs and aggregates that into a location-specific vehicle pricing search tool. The Carjojo work presented a great opportunity for End Point to utilize our technical skills to build a state-of-the-art application everyone is very proud of. End Point worked on the Carjojo development project from October of 2014 through early 2016, and the final Carjojo application launched in the summer of 2016. This case study shows that End Point can be a technology partner for a startup, enabling the client to maintain their own business once our part of the project is over.

Why End Point?

Reputation in full stack development

End Point has deep experience with full stack development so for a startup getting advice from our team can prove really helpful when deciding what technologies to implement and what timelines are realistic. Even though the bulk of the Carjojo work focused on specific development pieces, having developers available to help advise on the entire stack allows a small startup to leverage a much broader set of skills.

Startup Budget and Timelines

End Point has worked with a number of startups throughout our time in the business. Startups require particular focused attention on budget and timelines to ensure that the minimum viable product can be ready on time and that the project stays on budget. Our consultants focus on communication with the client and advise them on how to steer the development to meet their needs, even if those shift as the project unfolds.

Client Side Development Team

One of the best things about a lot of our clients is their technological knowledge and the team they bring to the table. In the case of Carjojo, End Point developers fit inside of their Carjojo team to build parts that they were unfamiliar with. End Point developers are easy to work with and already work in a remote development environment, so working in a remote team is a natural fit.

Client Side Project Management

End Point works on projects where either the project management is done in-house or by the client. In the case of a project like Carjojo where the client has technical project management resources, our engineers work within that team. This allows a startup like Carjojo insight into the project on a daily basis.

Project Overview

The main goal of the Carjojo project was to aggregate several data sources on car price and use data analytics to provide useful shopper information, and display that for their clients.
Carjojo?s staff had experience in the car industry and leveraged that to build a sizeable database of information. Analytics work on the database provided another layer of information, creating a time- and location-specific market value for a vehicle.

Carjojo kept the bulk of the database collection and admin work in house, as well as provided an in-house designer that closely worked with them on their vision for the project. End Point partnered to do the API architecture work as well as the front end development.

A major component of this project was using a custom API to pull information from the database and display it quickly with high end, helpful infographics. Carjojo opted to use APIs so that the coding work would seamlessly integrate with future plans for a mobile application, which normally require a substantial amount of recoding.

Creating a custom API also allows Carjojo to work with future partners and leverage their data and analytics in new ways as their business grows.

Team

Patrick Lewis: End Point project manager and front end developer. Patrick led development of the AngularJS front end application which serves as the main customer car shopping experience on the Carjojo site. He also created data stories using combinations of integrated Google Maps, D3/DimpleJS charts, and data tables to aid buyers with car searches and comparisons.



Matt Galvin: Front end developer. Matt led the efforts for data-visualization with D3 and DimpleJS. He created Angular services that were used to communicate with the backend, used D3 and DimpleJS to illustrate information graphically about cars, car dealers, incentives, etc., sometimes neatly packaging them into directives for easy re-use when the case fit. He also created a wealth of customizations and extensions of DimpleJS which allowed for rapid development without sacrificing visualization quality.



Josh Williams: Python API development. Josh led the efforts in connecting the database into Django and Python to process and aggregate the data as needed. He also used TastyPie to format the API response and created authentication structures for the API.

 




Project Specifics

API Tools

Carjojo?s project makes use of some of the best tools on the market today for accessing and displaying data. Django and Tastypie were chosen to allow for rapid API development and to keep the response time down on the website. In most cases the Django ORM was sufficient for generating queries from the data, though in some cases custom queries were written to better aggregate and filter the data directly within Postgres.

To use the location information in the database, some GIS location smarts were tied into Tastypie. Location searches tied into GeoDjango and generated PostGIS queries in the database.

Front End Tools

D3 is standard in data-visualization and is great for doing both simple and complicated graphics. Many of Carjojo?s graphs were bar graphs, pie charts and didn?t really require writing out D3 by hand. We also wanted to make many of them reusable and dynamic (often based on search terms or inputs) with use of Angular directives and services. This could have been done with pure D3, but Dimple makes creating simple D3 graphs easy and fast.

DimpleJS was used a lot in this project. Since Carjojo is data-driven, they wanted to display their information in an aesthetically pleasing manner and DimpleJS allowed us to quickly spin up information against some of the project?s tightest deadlines.

The approach worked well for most cases. However, sometimes Carjojo wanted something slightly different than what DimpleJS does out of the box. One example of DimpleJS customization work can be found here on our blog.

Another thing to note about the data visualizations was that sometimes when the data was plotted and graphed, it brought to light some discrepancies in the back-end calculations and analytics, requiring some back-and-forth between the Carjojo DBA and End Point.

Results

Carjojo had a successful launch of their service in the summer of 2016. Their system has robust user capabilities, a modern clean design, and a solid platform to grow from. The best news for Carjojo is that now the project has been turned back over to them for development. End Point believes in empowering our clients to move forward with their business and goals without us. Carjojo knows that we?ll be here for support if they need it.







Comments

published by noreply@blogger.com (Peter Hankiewicz) on 2016-04-21 23:00:00 in the "AngularJS" category

Introduction

The current state of development for web browsers is still problematic. We have multiple browsers, each browser has plenty of versions. There are multiple operating systems and devices that can be used. All of this makes it impossible to be sure that our code will work on every possible browser and system (unfortunately). With proper testing, we can make our product stable and good enough for production, but we can't expect that everything will go smoothly, well, it won't. He is always somewhere, a guy sitting in his small office and using outdated software, Internet Explorer 6 for example. Usually you want to try to support as many as possible users, here, I will explain how to help find them. Then you just need to decide if it is worth fixing an issue for them.

Browser errors logging

What can really help us and is really simple to do is browser error logging. Every time an error occurs on the client side (browser will generate an error that the user most likely won't see), we can log this error on the server side, even with a stack trace. Let's see an example:

window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
    $.post('//your.domain/client-logs', function () {
        errorMsg: errorMsg,
        url: url,
        lineNumber: lineNumber,
        column: column,
        errorObj: errorObj
    });
        
    // Tell browser to run its own error handler as well   
    return false;
};

What do we have here? We bind a function to the window.onerror event. Every time an error occurs this function will be called. Some arguments are passed together:

  • errorMsg - this is an error message, usually describing why an error occurred (for example: "Uncaught ReferenceError: heyyou is not defined"),
  • url - current url location,
  • lineNumber - script line number where an error happened,
  • column - the same as above but about column,
  • errorObj - the most important part here, an error object with a stack trace included.

What to do with this data? You will probably want to send it to a server and save it, to be able to go through this log from time to time like we do in our example:

$.post('//your.domain/client-logs', function () {
    errorMsg: errorMsg,
    url: url,
    lineNumber: lineNumber,
    column: column,
    errorObj: errorObj
});

It's very helpful, usually with proper unit and functional testing errors generated are minor, but sometimes you may find a critical issue before a bigger number of clients will actually discover it. It is a big profit.

JSNLog

JSNLog is a library that helps with client error logging. You can find it here: http://jsnlog.com/. I can fully recommend using this one, it can also do the AJAX calls, timeout handling, and many more.

Client error notification

If you want to be serious and professional every issue should be reported to a user in some way. On the other side, it's sometimes dangerous to do if the user will be spammed with information that an error occurred because of some minor error. It's not easy to find the best solution because it's not easy to identify an error priority.

Just from experience, if you have a system where users are logged on, you can create a simple script that will send an email to a user with a question regarding an issue. You can set up a limit value to avoid sending too many messages. If the user will be interested he can always reply and explain an issue. Usually the user will appreciate this interest.

Errors logging in Angular

It's worth mentioning how we can handle error logging in the Angular framework, with useful stack traces and error descriptions. See an example below:

First we need to override default log functions in Angular:

angular.module('logToServer', [])
  .service('$log', function () {
    this.log = function (msg) {
      JL('Angular').trace(msg);
    };
    this.debug = function (msg) {
      JL('Angular').debug(msg);
    };
    this.info = function (msg) {
      JL('Angular').info(msg);
    };
    this.warn = function (msg) {
      JL('Angular').warn(msg);
    };
    this.error = function (msg) {
      JL('Angular').error(msg);
    };
  });

Then override exception handler to use our function:

factory('$exceptionHandler', function () {
    return function (exception, cause) {
      JL('Angular').fatalException(cause, exception);
      throw exception;
    };
  });

We also need an interceptor to handle AJAX call errors. This time we need to override $q object like this:

factory('logToServerInterceptor', ['$q', function ($q) {
    var myInterceptor = {
      'request': function (config) {
          config.msBeforeAjaxCall = new Date().getTime();

          return config;
      },
      'response': function (response) {
        if (response.config.warningAfter) {
          var msAfterAjaxCall = new Date().getTime();
          var timeTakenInMs = msAfterAjaxCall - response.config.msBeforeAjaxCall;

          if (timeTakenInMs > response.config.warningAfter) {
            JL('Angular.Ajax').warn({ 
              timeTakenInMs: timeTakenInMs, 
              config: response.config, 
              data: response.data
            });
          }
        }

        return response;
      },
      'responseError': function (rejection) {
        var errorMessage = "timeout";
        if (rejection && rejection.status && rejection.data) {
          errorMessage = rejection.data.ExceptionMessage;
        }
        JL('Angular.Ajax').fatalException({ 
          errorMessage: errorMessage, 
          status: rejection.status, 
          config: rejection.config }, rejection.data);
        
          return $q.reject(rejection);
      }
    };

    return myInterceptor;
  }]);

How it looks all together:

angular.module('logToServer', [])
  .service('$log', function () {
    this.log = function (msg) {
      JL('Angular').trace(msg);
    };
    this.debug = function (msg) {
      JL('Angular').debug(msg);
    };
    this.info = function (msg) {
      JL('Angular').info(msg);
    };
    this.warn = function (msg) {
      JL('Angular').warn(msg);
    };
    this.error = function (msg) {
      JL('Angular').error(msg);
    };
  })
  .factory('$exceptionHandler', function () {
    return function (exception, cause) {
      JL('Angular').fatalException(cause, exception);
      throw exception;
    };
  })
  .factory('logToServerInterceptor', ['$q', function ($q) {
    var myInterceptor = {
      'request': function (config) {
          config.msBeforeAjaxCall = new Date().getTime();

          return config;
      },
      'response': function (response) {
        if (response.config.warningAfter) {
          var msAfterAjaxCall = new Date().getTime();
          var timeTakenInMs = msAfterAjaxCall - response.config.msBeforeAjaxCall;

          if (timeTakenInMs > response.config.warningAfter) {
            JL('Angular.Ajax').warn({ 
              timeTakenInMs: timeTakenInMs, 
              config: response.config, 
              data: response.data
            });
          }
        }

        return response;
      },
      'responseError': function (rejection) {
        var errorMessage = "timeout";
        if (rejection && rejection.status && rejection.data) {
          errorMessage = rejection.data.ExceptionMessage;
        }
        JL('Angular.Ajax').fatalException({ 
          errorMessage: errorMessage, 
          status: rejection.status, 
          config: rejection.config }, rejection.data);
        
          return $q.reject(rejection);
      }
    };

    return myInterceptor;
  }]);

This should handle most of the errors that could happen in the Angular framework. Here I used the JSNLog library to handle sending logs to a server.

Almost the end

There are multiple techniques for logging errors on a client side. It does not really matter which one you choose, it only matters that you do it. Especially when it's really a little amount of time to invest and make it work and a big profit in the end.


Comments

published by noreply@blogger.com (??????? ???????) on 2016-02-19 03:36:00 in the "AngularJS" category

Let me tell you about my own town

I was born in Yekaterinburg. It's a middle-sized town in Russia.
Most likely you don't know where it is. So let me show you:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Hello World!</title>
    <script src="/cesium/Build/Cesium/Cesium.js"></script>
    <link rel="stylesheet" href="layout.css"></link>
  </head>
<body>
  <div id="cesiumContainer"></div>
  <script>
    var viewer = new Cesium.Viewer('cesiumContainer');
    (function(){
        var ekb = viewer.entities.add({
          name : 'Yekaterinburg',
          // Lon, Lat coordinates
          position : Cesium.Cartesian3.fromDegrees(60.6054, 56.8389),
          // Styled geometry
          point : {
            pixelSize : 5,
          color : Cesium.Color.RED
          },
          // Labeling
          label : {
            text : 'Yekaterinburg',
            font : '16pt monospace',
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            outlineWidth : 2,
            verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
            pixelOffset : new Cesium.Cartesian2(0, -9)
          }
        });
        
        // How to place camera around point
        var heading = Cesium.Math.toRadians(0);
        var pitch = Cesium.Math.toRadians(-30);
        viewer.zoomTo(ekb, new Cesium.HeadingPitchRange(heading, pitch, 10000));
    })();
  </script>
</body>
</html>

Now, I would like to tell you about the history of my town. In the beginning it was a fortified metallurgical plant with a few residential blocks and some public buildings. It was relatively small.

I could say that its size was about the size of a modern city-center, but that description is too vague. I think the best way to tell you something about the city is with a map.

I'll show you two maps.

  1. A map from 1750, early in the town's history when it was just a factory: http://www.retromap.ru/m.php#r=1417506
  2. A map from 1924 at about the start of Soviet industrialization, just before Yekaterinburg became the industrial center of the Urals: http://www.retromap.ru/m.php#r=1419241
Thanks for these beautiful maps to http://www.retromap.ru.

The map from 1750 is a small image, so I've added it via SingleTileImageryProvider. Just specifying the src and coordinates:

function setupImagery() {
    var layers = viewer.scene.imageryLayers;
        
    var s = 56.8321929;
    var n = 56.8442609;
    var w = 60.5878970;
    var e = 60.6187892;
    var l1750 = layers.addImageryProvider(new Cesium.SingleTileImageryProvider({
        url : 'assets/1750.png',
        rectangle : Cesium.Rectangle.fromDegrees(w,s,e,n)
    }));
    l1750.alpha = 0.75;
}

Now you can see how small my town was initially.

The second image is larger, so I've split it up into tiles. If you use gdal2tiles.py for generating tiles, it creates all the metadata necessary for TMS and you are able connect the imagery set via TileMapServiceImageryProvider. Otherwise, you can use UrlTemplateImageryProvider.

var l1924 = layers.addImageryProvider(new Cesium.TileMapServiceImageryProvider({
    url: 'assets/1924t',
    minimumLevel: 8,
    maximumLevel: 16,
    credit: 'retromap.ru'
}));

l1924.alpha = 0.75;

I've used QGIS for geo referencing. Here is a good tutorial.

User interface and Angular.js

And below here you see how I've added some controls for visibility and opacity of the overlays. Later we will bind them with an Angular-driven GUI:

// APP is global

var layersHash = {
    'l1750': l1750,
    'l1924': l1924
}

APP.setAlpha = function(layer, alpha) {
    if(layersHash[layer] && layersHash[layer].alpha !== undefined) {
        layersHash[layer].alpha = alpha;
    }            
};

APP.show = function(layer) {
    if(layersHash[layer] && layers.indexOf(layersHash[layer]) < 0) {
        layers.add(layersHash[layer]);
    }            
};

Why not keep our views in a namespace and access them directly from an Angular controller? Using this approach will give us a lot of flexibility:

  • You can split up the GUI and Cesium modules and use something else instead of Cesium or Angular.
  • You are able to make a proxy for `APP` and add business logic to the calls made to it.
  • It just feels right not to meld all parts of the application into one unmanageble mish-mash of code.

For the GUI I've added a big slider for the timeline, small sliders for layer opacity, checkboxes for visibility, and call APP methods via Angular's $watch.

$scope.$watch('slider.value', function() {
    var v = $scope.slider.options.stepsArray[$scope.slider.value];
    if (v >= 1723 && v <= 1830) {
        $scope.menu.layers[0].active = true;
        $scope.menu.layers[1].active = false;
    }
    if (v > 1830 && v < 1980) {
        $scope.menu.layers[0].active = false;
        $scope.menu.layers[1].active = true;
    }
    if(v >= 1980) {
        $scope.menu.layers[0].active = false;
        $scope.menu.layers[1].active = false;
    }
    
    $scope.updateLayers();
});

$scope.updateLayers = function() {
    for (var i = 0; i < $scope.menu.layers.length; i++) {
        if ($scope.menu.layers[i].active ) {
            APP.show && APP.show($scope.menu.layers[i].name);
        }
        else {
            APP.hide && APP.hide($scope.menu.layers[i].name);
        }
    }
};

Back to the history:

Yekaterinburg was founded on November 7, 1723. This is the date of the first test-run of the forging hammers in the new factory. The original factory design by Tatishew had 40 forging hammers and 4 blast furnaces. That may well have made it the best equipped and most productive factory of its time.
Now I want to add text to the application. Also, I have some cool pictures of the hammers and furnaces. Adding an overlay for text and binding its content is a matter of CSS and ng-include/ng-bind knowledge and it's a bit out of scope for this post, but let's push on and add some pictures and link them to the timeline. Cesium has KmlDataSource for KML loading and parsing. This is how my application loads and accesses these attributes:
var entityByName = {};
var promise = Cesium.KmlDataSource.load('assets/foto.kml');
promise.then(function(dataSource) {
    viewer.dataSources.add(dataSource);
    
    //KML entities
    var entities = dataSource.entities.values;
    for (var i = 0; i < entities.length; i++) {
        var entity = entities[i];
        // <Data> attributes, parsed into js object
        var ed = entity.kml.extendedData;
        
        entityByName[entity.id] = {
            'entity': entity,
            since: parseInt(ed.since.value),
            to: parseInt(ed.to.value)
        };
    }
});

Add bindings for Angular:

APP.filterEtityByY = function(y) {
    for (var k in entityByName) {
        if(entityByName.hasOwnProperty(k)) {
            var s = entityByName[k].since;
            var t = entityByName[k].to;
            entityByName[k].entity.show = (y >= s && y <= t);
        }
    }
};

var heading = Cesium.Math.toRadians(0);
var pitch = Cesium.Math.toRadians(-30);
var distanceMeters = 500;
var enityHeading = new Cesium.HeadingPitchRange(heading, pitch, distanceMeters);

APP.zoomToEntity = function(name) {
    if(name && entityByName[name]) {
        viewer.zoomTo(entityByName[name].entity, enityHeading);
    }
};
I've added object timespans via extended data. If you want to use the Cesium/GE default timeline, you should do it via a TimeSpan section in the KML's entries:

  2000-01-00T00:00:00Z
    2000-02-00T00:00:00Z
 

Another interesting fact about my town is that between 1924 and 1991 it had a different name: Sverdlovsk (??????????). So I've added town name changing via APP and connected it to the timeline.

Using APP.filterEtityByY and APP.zoomToEntity it's relatively easy to connect a page hash like example.com/#!/feature/smth with features from KML. One point to note is that I use my own hash's path part parser instead of ngRoute's approach.

You can see how all these elements work together at https://dmitry.endpoint.com/cesium/ekb, the sources are on Github at https://github.com/kiselev-dv/EkbHistory/tree/master.


Comments

published by noreply@blogger.com (Sam Batschelet) on 2015-12-30 18:14:00 in the "AngularJS" category

The 2015 Perl Dancer Conference has recently released the presentation videos. This year the conference was hosted in beautiful Vienna, Austria. Josh Lavin and I were both honored to attend the conference as well as give talks. Earlier, Josh wrote summaries of the conference:

Conference Recap

Conference Presentations

SpaceCamps ?The Final Frontier?

I gave a talk exploring new technologies for End Point's own DevCamps development tool. During the presentation I detailed my research into containers and what a cloud-based development environment might look like.

SpaceCamps Presentation Video

AngularJS & Dancer for Modern Web Development

Josh detailed his experience migrating legacy applications utilizing Dancer, AngularJS, and modern Perl techniques. Josh highlighted the challenges he faced during the process, as well as lessons he learned along the way.

AngularJS & Dancer for Modern Web Development Presentation Video

Lightning Talks

Josh and I both gave short ?lightning talks.? Josh?s was on Writing Unit Tests for a Legacy App (Interchange 5), and mine was on Plack & Interchange 5.

To review the rest of the presentations please checkout the Perl Dancer Conference YouTube channel.

Summary

The Perl Dancer community continues to flourish and the conference this year hosted a record 5 core Dancer developers. Dancer is about to release the finalized version of its long awaited plugin infrastructure for Dancer2. A lot of work on this was completed during the conference. Being an organizer of the conference, it brings me great joy to see this success. This news along with the release of Perl 6, I am certain 2016 will be a wonderful year for not only Dancer but the entire Perl community.


Comments

published by noreply@blogger.com (Josh Lavin) on 2015-10-30 17:00:00 in the "AngularJS" category

At the Perl Dancer Conference 2015, I gave a talk on AngularJS & Dancer for Modern Web Development. This is a write-up of the talk in blog post form.

Legacy Apps

It's a fact of life as a software developer that a lot of us have to work with legacy software. There are many older platforms out there, still being actively used today, and still supporting valid businesses. Thus, legacy apps are unavoidable for many developers. Eventually, older apps are migrated to new platforms. Or they die a slow death. Or else the last developer maintaining the app dies.

Oh, to migrate

It would be wonderful if I could migrate every legacy app I work on to something like Perl Dancer. This isn't always practical, but a developer can dream, right?

Of course, every circumstance is different. At the very least, it is helpful to consider ways that old apps can be migrated. Using new technologies can speed development, give you new features, and breathe new life into a project, often attracting new developers.

As I considered how to prepare my app for migration, here are a few things I came up with:

  • Break out of the Legacy App Paradigm
    • Consider that there are better ways to do things than the way they've always been done
  • Use Modern Perl
  • Organize business logic
    • Try to avoid placing logic in front-end code

You are in a legacy codebase

I explored how to start using testing, but I soon realized that this requires methods or subroutines. This was the sad realization that up till now, my life as a Perl programmer had been spent doing scripting. My code wasn't testable, and looked like a relic with business logic strewn about.

Change

I set out to change my ways. I started exploring object-oriented Perl using Moo, since Dancer2 uses Moo. I started trying to write unit tests, and started to use classes and methods in my code.

Essentially, I began breaking down problems into smaller problems. This, after all, is how the best methods are written: short and simple, that do just one thing. I found that writing code this way was fun.

Crash

I quickly realized that I wasn't able to run tests in my Legacy App, as it couldn't be called from the command line (at least not out of the box, and not without weird hacks). Thus, if my modules depended on Legacy App code, I wouldn't be able to call them from tests, because I couldn't run these tests from the shell.

This led me to a further refinement: abstract away all Legacy App-specific code from my modules. Or, at least all the modules I could (I would still need a few modules to rely on the Legacy App, or else I wouldn't be using it it all). This was a good idea, it turned out, as it follows the principle of Separation of Concerns, and the idea of Web App + App, which was mentioned frequently at the conference.

Now I was able to run tests on my modules!

Move already

This whole process of "getting ready to migrate" soon began to look like yak shaving. I realized that I should have moved to Dancer earlier, instead of trying to do weird hacks to get the Legacy App doing things as Dancer would do them.

However, it was a start, a step in the right direction. Lesson for me, tip for you.

And, the result was that my back-end code was all the more ready for working with Dancer. I would just need to change a few things, and presto! (More on this below.)

Front-End

With the back-end looking tidier, I now turned to focus on the front-end. There was a lot of business logic in my front-end code that needed to be cleaned up.

Here is an example of my Legacy App front-end code:

@_TOP_@
<h1>[scratch page_title]</h1>
[perl]
   my $has_course;
   for (grep {$_->{mv_ib} eq 'course'} @$Items) {
      $has_course++;
   }
   return $has_course ? '

You have a course!

' : ''; [/perl] <button>Buy [if cgi items]more[else]now[/else][/if]</button> @_BOTTOM_@

As you can see, the Legacy App allowed the embedding of all sorts of code into the HTML page. I had Legacy App tags (in the brackets), plus something called "embedded perl", plus regular HTML. Add all this together and you get Tag Soup.

This kind of structure won't look nice if you attempt to view it on your own machine in a web browser, absent from the Legacy App interpreting it. But let's face it, this code doesn't look nice anywhere.

Separation of Concerns

I thought about how to apply the principle of Separation of Concerns to my front-end code. One thing I landed on, which isn't a new idea by any means, is the use of "HTML + placeholders," whereby I would use some placeholders in my HTML, to be later replaced and filled in with data. Here is my first attempt at that:

@_TOP_@
[my-tag-attr-list 
    page_title="[scratch page_title]"
    has_course="[perl] ... [/perl]"
    buy_phrase="Buy [if cgi items]more[else]now[/else][/if]"
]

    <h1>{PAGE_TITLE}</h1>
    {HAS_COURSE?}<p>You have a course!</p>{/HAS_COURSE?}
    <button>{BUY_PHRASE}</button>

[/my-tag-attr-list]
@_BOTTOM_@

What I have here uses the Legacy App's built-in placeholder system. It attempts to set up all the code in the initial "my-tag-attr-list", then the HTML uses placeholders (in braces) which get replaced upon the page being rendered. (The question-mark in the one placeholder is a conditional.)

This worked OK. However, the logic was still baked into the HTML page. I wondered how I could be more ready for Dancer? (Again, I should have just gone ahead and migrated.) I considered using Template::Toolkit, since it is used in Dancer, but it would be hard to add to my Legacy App.

Enter AngularJS (or your favorite JavaScript framework)

AngularJS is a JavaScript framework for front-end code. It displays data on your page, which it receives from your back-end via JSON feeds. This effectively allows you to separate your front-end from your back-end. It's almost as if your front-end is consuming an API. (Novel idea!)

After implementing AngularJS, my Legacy App page looked like this (not showing JavaScript):

@_TOP_@
<h1 ng-bind="page.title"></h1>
<p ng-if="items.course">You have a course!</p>
<button ng-show="items">Buy more</button>
<button ng-hide="items">Buy now</button>
@_BOTTOM_@

Now all my Legacy App is doing for the front-end is basically "includes" to get the header/footer (the TOP and BOTTOM tags). The rest is HTML code with ng- attributes. These are what AngularJS uses to "do" things.

This is much cleaner than before. I am still using the Legacy App back-end, but all it has to do is "routing" to call the right module and deliver JSON (and do authentication).

Here's a quick example of how the JavaScript might look:

<html ng-app="MyApp">
...
<script src="angular.min.js"></script>
<script>
  angular.module / factory / controller
  $scope.items = ...;
</script>
</html>

This is very simplified, but via its modules/factories/controllers, the AngularJS code handles how the JSON feeds are displayed in the page. It pulls in the JSON and can massage it for use by the ng- attributes, etc.

I don't have to use AngularJS to do this — I could use a Template::Toolkit template delivered by Dancer, or any number of other templating systems. However, I like this method, because it doesn't require a Perl developer to use. Rather, any competent JavaScript developer can take this and run with it.

Migration

Now the migration of my entire app to Dancer is much easier. I gave it a whirl with a handful of routes and modules, to test the waters. It went great.

For my modules that were the "App" (not the "Web App" and dependent on the Legacy App), very few changes were necessary. Here is an example of my original module:

package MyApp::Feedback;
use MyApp;
my $app = MyApp->new( ... );
sub list {
    my $self = shift;
    my $code = shift
        or return $app->die('Need code');
    my $rows = $app->dbh($feedback_table)->...;
    return $rows;
}

You'll see that I am using a class called MyApp. I did this to get a custom die and a database handle. This isn't really the proper way to do this (I'm learning), but it worked at the time.

Now, after converting that module for use with Dancer:

package MyApp::Feedback;
use Moo;
with MyApp::HasDatabase;
sub list {
    my $self = shift;
    my $code = shift
        or die 'Need code';
    my $rows = $self->dbh->...;
    return $rows;
}

My custom die has been replaced with a Perl die. Also, I am now using a Moo::Role for my database handle. And that's all I changed!

Before

The biggest improvements were in things that I "stole" from Dancer. (Naturally, Dancer would do things better than I.) This is my Legacy App's route for displaying and accepting feedback entries. It does not show any authentication checks. It handles feeding back an array of entries for an item ("list"), a single entry (GET), and saving an entry (POST):

sub _route_feedback {
    my $self = shift;
    my (undef, $sub_action, $code) = split '/', $self->route;
    $code ||= $sub_action;
    $self->_set_status('400 Bad Request');   # start with 400
    my $feedback = MyApp::Feedback->new;
    for ($sub_action) {
        when ("list") {
            my $feedbacks = $feedback->list($code);
            $self->_set_tmp( to_json($feedbacks) );
            $self->_set_path('special/json');
            $self->_set_content_type('application/json; charset=UTF-8');
            $self->_set_status('200 OK') if $feedbacks;
        }
        default {
            for ($self->method) {
                when ('GET') {
                    my $row = $feedback->get($code)
                        or return $self->_route_error;
                    $self->_set_tmp( to_json($row) );
                    $self->_set_path('special/json');
                    $self->_set_content_type('application/json; charset=UTF-8');
                    $self->_set_status('200 OK') if $row;
                }
                when ('POST') {
                    my $params = $self->body_parameters
                        or return $self->_route_error;
                    $params = from_json($params);
                    my $result = $feedback->save($params);
                    $self->_set_status('200 OK') if $result;
                    $self->_set_path('special/json');
                    $self->_set_content_type('application/json; charset=UTF-8');
                }
            }
        }
    }
}

After

Here are those same routes in Dancer:

prefix '/feedback' => sub {
    my $feedback = MyApp::Feedback->new;
    get '/list/:id' => sub {
        return $feedback->list( param 'id' );
    };
    get '/:code' => sub {
        return $feedback->get( param 'code' );
    };
    post '' => sub {
        return $feedback->save( scalar params );
    };
};

Dancer gives me a lot for free. It is a lot simpler. There's still no authentication shown here, but everything else is done. (And I can use an authentication plugin to make even that easy.)

TMTOWTDI

For the front-end, we have options on how to use Dancer. We could have Dancer deliver the HTML files that contain AngularJS. Or, we could have the web server deliver them, as there is nothing special about them that says Dancer must deliver them. In fact, this is especially easy if our AngularJS code is a Single Page App, which is a single static HTML file with AngularJS "routes". If we did this, and needed to handle authentication, we could look at using JSON Web Tokens.

Now starring Dancer

In hindsight, I probably should have moved to Dancer right away. The Legacy App was a pain to work with, as I built my own Routing module for it, and I also built my own Auth checking module. Dancer makes all this simpler.

In the process, though, I learned something...

Dancer is better?

I learned you can use tools improperly. You can do Dancer "wrong". You can write tag soup in anything, even the best modern tools.

You can stuff all your business logic into Template::Toolkit tags. You can stuff logic into Dancer routes. You can do AngularJS "wrong" (I probably do).

Dancer is better:

Dancer is better when (thanks to Matt S Trout for these):

  • Routes contain code specific to the Web.
  • Routes call non-Dancer modules (where business logic lives; again, Web App + App).
  • The route returns the data in the appropriate format.

These make it easy to test. You are effectively talking to your back-end code as if it's an API. Because it is.

The point is: start improving somewhere. Maybe you cannot write tests in everything, but you can try to write smart code.

Lessons learned

  • Separate concerns
  • Keep it testable
  • Just start somewhere

The end. Or maybe the beginning...


Comments

published by noreply@blogger.com (Szymon Guz) on 2015-03-24 08:54:00 in the "AngularJS" category

The best thing in AngularJS is the great automation of actualizing the data in the html code.

To show how easy Angular is to use, I will create a very simple page using AngularJS and Github.

Every Github user can get lots of notifications. All of them can be seen at Github notification page. There is also the Github API, which can be used for getting the notification information, using simple http requests, which return jsons.

I wanted to create a simple page with a list of notifications. With information if the notification was read (I used "!!!" for unread ones). And with automatical refreshing every 10 minutes.

To access the Github API, first I generated an application token on the Github token page. Then I downloaded a file from the AngularJS page, and a Github API javascript wrapper.

Then I wrote a simple html file:

 
    <html>
      <head>
        
        
        
        
      </head>

      <body ng-app="githubChecker">
        

Github Notifications

!!! {{ n.subject.title }}
</body> </html>

This is the basic structure. Now we need to have some angular code to ask Github for the notifications and fill that into the above html.

The code is also not very complicated:

  var githubChecker = angular.module('githubChecker', []);

  githubChecker.controller("mainController", ['$scope', '$interval', function($scope, $interval){

    $scope.notifications = [];

    var github = new Github({
      username: "USERNAME",
      token:    "TOKEN",
      auth:     "oauth"
    });
    var user = github.getUser();

    var getNotificationsList = function() {
      user.notifications(function(err, notifications) {
        $scope.notifications = notifications;
        $scope.$apply();
      });
    };

    getNotificationsList();

    $interval(getNotificationsList, 10*60*1000);

  }]);

First of all I've created an Angular application object. That object has one controller, in which I created a Github object, which gives me a nice way to access the Github API.

The function getNotificationsList calls the Github API, gets a response, and just stores it in the $scope.notifications object.

Then the angular's magic comes into play. When the $scope fields are updated, angular automatically updates all the declarations in the html page. This time it is not so automatic, as I had to call the $scope.$apply() function to trigger it. It will loop through the $scope.notifications and update the html.

For more information about the Angular, and the commands I used, you can check the AngularJS Documentation.


Comments

published by noreply@blogger.com (Kamil Ciemniewski) on 2015-02-05 09:57:00 in the "AngularJS" category

Some time ago, our CTO, Jon Jensen, sent me a link to a very interesting blog article about AngularJS. I have used the AngularJS framework in one of our internal projects and have been (vocally) very pleased with it ever since. It solves many problems of other frameworks and it makes you quite productive as a developer, if you know what you?re doing. It?s equally true that even the best marketed technology is no silver bullet in real life. Once you?ve been through a couple of luckless technology-crushes, you tend to stay calm ? understanding that in the end there?s always some tradeoff. We?re trying to do our best at finding a balance between chasing after the newest and coolest, and honoring what?s already stable and above all safe. Because the author of the blog article decided to point at some elephants in the room ? it immediately caught our attention. I must admit that the article resonates with me somewhat. I believe, though, that it also doesn?t in some places. While I don?t have as much experience with Angular as this article?s author, I clearly see him sometimes oversimplifying, overgeneralizing, and being vague. I?d like to address many of the author's points in detail, so I will quote sections of the article. The author says:

My verdict is: Angular.js is ?good enough? for majority of projects, but it is not good enough for professional web app development. ? When I say ?professional web app? I mean the app, which is maintainable in a long run, performant in all reasonably modern browsers, has a smooth UX and is mobile-friendly.

The first example that meets those requirements is our internal project. Saying that Angular isn?t a good fit for author?s definition of ?professional web apps? is IMHO a huge overgeneralization. Jon Jensen shared with me the following thoughts on this:

It is also worth asking what is meant by ?maintainable in the long run?, since pretty much any web application will need a significant overhaul within 5 years or so, and heavy browser-based JavaScript apps are more likely to need a major overhaul sooner than that. That's partly because front-end technology and browser competition is moving so quickly, but also because JavaScript frameworks are improving so rapidly. It's impossible to predict whether a given framework will be maintained for 5 years, but even more impossible to say whether you would want to keep using it after that long.

Those questions make sense to me. The long run may not be so long for modern JavaScript apps. Later the blog writer asks:

Are there any use cases where Angular shines?
  • Building form-based "CRUD apps".
  • Throw-away projects (prototypes, small apps).
  • Slow corporate monoliths, when performance does not matter and maintenance costs are not discussed (hm, but have you looked at ExtJS?)
This is true but is also constrained IMHO. Counter examples are to be found all over the Internet. The YouTube application for Sony's PlayStation 3 is only one of them. One can use e.g. https://builtwith.angularjs.org to browse others.

And what are no-no factors for angular?

  • Teams with varying experience.
  • Projects, which are intended to grow.
  • Lack of highly experienced frontend lead developer, who will look through the code all the time.
  • Project with 5 star performance requirements.
I agree with the last one. Other ones sprout from the fact that Angular is so liberal in how the app may be structured. In some cases it?s good, while in some bad ? there?s always some tradeoff. I?d compare Angular to Sinatra and Ember to Rails. Both are intended to be used in different use cases. One isn?t superior to another without a context.

It there any Working Strategy, if you are FORCED to work with angular?

  • Taking angular for fast prototyping is OK, hack it and relax.
  • After the prototype is proved to be the Thing-To-Go, kill the prototype. DO NOT GROW IT!
  • Sit and analyze the design mistakes you've made.
  • Start a fresh new project, preferably with other tech stack.
  • Port the functionality from the prototype to your MVP.
Agreed with #1. Maintainability isn?t trivial with Angular ? it?s true. One reason is that with dependency injection there?s a possibility that with growing number of modules, some tries will depend on each other in a circular way: A -> B -> C -> A

But it?s not inherent to Angular but to dependency injection itself and there are known strategies for dealing with that. Other reason is that it?s so liberal and yes ? you have to always be alert, making sure the code grows in the good direction. It?s also true that many teams who have previously been using other MV{C,P} frameworks ? are converting to Angular. Why? I gave the answer in the first paragraph ? there?s no silver bullet. If you want a truly orthogonal software you don?t grow it with just great tools ? but with great people. And sometimes even having a star-level team isn?t enough because of the degree to which business requirements change.

Then:

If you still need to grow your project and maintain it in the future:
  • Accept the fact that you will suffer in the future. The lowered expectations will help you stay happy sometimes.
  • Create a thorough guideline based on the popular things (this, this and that) covering all the use cases and patterns you can imagine.
  • Try to keep things as loosely coupled as possible with your OOD knowledge.
  • Choose either MVC or MVVM, but do not start by mixing approaches.
  • Include "refactoring" iterations in your dev process (good interval - each 3 months).
  • Analyze your usage patterns and use cases periodically.
  • Create a metaframework based on angular, tailored SPECIFICALLY for your project needs and your team experience!
Agreed with all of those. I?d agree with those really for any technology there?s out there.

Then the author says:

Dependency injection lacks some functionality you will need sometime.

That intrigues me and I?ll look for similar opinions by others that explain in details why the writer thinks that dependency injection will leave me stuck without needed functionality someday. Then:

Directives are overloaded with responsibilities (ever wonder why and when you should use isolated scope? Yeah, that's only the tip of the iceberg).

I don?t really think that?s a problem because a directive only has the amount of responsibility you make it have. One can use or abuse any technology so this point doesn?t really resonate with me. Then:

Modules are not real modules.
  • No CommonJS/AMD.
  • No custom lazy loading.
  • No namespaces.
You can use modules only to specify the dependency graph and get rid of specifying the correct file order for injecting scripts (which is not a problem anyway if you are using component-based structure and, for example, browserify).

That?s only a half-truth. You can use e.g. RequireJS and have ?real modules? with Angular ? there?s even a good blog article describing how to do it: http://www.sitepoint.com/using-requirejs-angularjs-applications/. If you were to use just Angular-flavored modules one issue you might run into though could be name clashes. But then unless you want to use a dozen of 3rd party modules you find on GitHub ? name clashes aren?t a real problem out there in the wild. And also if you do want to use those modules, you cannot expect to have a ?maintainable? codebase over time anyway can you?

$scope is "transparent" and inherited by default. Inheritance is known to be an antipattern in OOD. (Proof?) You MUST know the cases, when it can be useful. Angular forces you to get rid of this inheritance all the time.

I somewhat agree. Managing scopes is sometimes a pain.

Bidirectional binding is unpredictable and hard to control (unless you know that you MUST control it).

That for me falls under the ?use or misuse potential? category. I can?t see it causing any problem unless you create a huge nest of dependent variables and want then to debug if it goes wrong (there are cleaner ways to achieve the same results).

Transparent scope and "referential hell" mean that you CANNOT KNOW what part of the system will be updated when you introduce a change using $scope.$apply(). You have no guarantees. This is a design tradeoff. Do you know that each time you call $scope.$apply() you actually call $rootScope.$apply()? And this call updates all scopes and run all your watches? Moreover, $rootScope.$apply() is called each time when: $timeout handler is invoked (almost all debounce services are broken by design) $http receives a response (yeah, if you have a polling implemented on $http ...) any DOM handler is called (have you throttled your ng-mouseovers? They actually invoke ALL your $watches, and built-in digest phasing does not really help) If you know, that some change is localised (like, if you click the button, only the same $scope will be affected), then you MUST use $scope.$digest. But again, you will face nasty "$digest is already in progress" issue...

This is a huge annoyance. He?s right about it. Then:

Yes, angular is complex and have a terrible learning curve. The worst thing is that you are learning framework for sake of learning framework.

I?d say quite the contrary is true. When we switched to Angular with the our internal app, no-one on the team had any experience with it. The team was ranging in experience ? from ?not much outside of jQuery? to some much more experienced with many JavaScript frameworks. Yet the team started producing much more almost right away. I also heard them saying that Angular is much easier than our previous setup ? which was Backbone + KnockoutJS.

Then:

90% of those modules in the wild are broken by design.
  • They are not really performant
  • They do not scale
  • They misuse some of angular features
  • They are badly designed and forces bad practices
  • But hey, who cares? They do their job anyway, right?
This is true. I?d just add that it?s not really only inherent to Angular. If you?ve been a developer long enough you can recall probably hundreds of hours of fighting with someone else?s code which doesn?t work the way you?d expect it or was marketed as. The problem is there whether you?re trying some Angular modules, other JavaScript libraries and their plugins or other languages libraries too. You always have to be very careful when pulling in third party code into your application.

  • Those docs suck. They still suck.
  • There are no reference projects.
  • There is no reference project structure.
  • No one share their experience with you through the framework.
  • Yes, those practices can be overwhelming (I am looking at you, Ember). But it's better to have overwhelming practices, than to have none.
  • Some encoded practices are questionable:
  • Blocking the UI while resolving all promises? Really?
  • No subrouting? Hmmm
I somewhat agree and somewhat disagree with those. There are reference projects on GitHub. The documentation was my friend really. Not having a rigid standard of doing things is good or bad only within a context.

I don?t want to come across as someone who thinks he has all the answers and knows more than others. This is just my perspective regarding the things enclosed in this article. I?d say mostly I agree with the author (with exceptions stated above). I?d also say that I cannot see any technology that would be entirely free of shortcomings. I think it?s worth noting that Angular team seems to be aware of them. They?re already working on the next version: Angular 2. You can read some more about this project here: http://ng-learn.org/2014/03/AngularJS-2-Status-Preview/. There?s nothing perfect in this world, but the best thing we can do is to continuously follow the path of constant never-ending improvement.
Comments

published by noreply@blogger.com (Marina Lohova) on 2015-01-13 15:00:00 in the "AngularJS" category

To all of you window.onResize aficionados, I dedicate this blog post because today we will be doing a lot of dynamic resizing in JavaScript. All of it will be done completely and effortlessly with my one-page long Angular directive.

Why do I need to attach an expensive onResize handler to my already overloaded page, you ask. The answer is very simple. Our app layout is pixel-perfect. Each element has the predefined width and margins. Yet, the app needs to look good on all kind of devices, from regular PC to tablet to iPhone. That's why I created the following Angular directive in /scripts/directives/tsResize.js:

angular.module('angularApp')
.directive('tsResize', function($window) {
 return function(scope, element) {
   var w = angular.element($window);
   scope.getWindowDimensions = function () {
     return {
       'h': $window.innerHeight,
       'w': $window.innerWidth
     };
   };
   scope.$watch(scope.getWindowDimensions, 
              function (newValue, oldValue) {
     scope.windowHeight = newValue.h;
     scope.windowWidth = newValue.w;

     scope.mainContainerStyle = function () {
       if (newValue.w > 890) {
         return {};
       } else {
         val = newValue.w/890;
         return {
           '-webkit-transform': 'scale(' + val + ')',
           '-o-transform': 'scale(' + val + ')',
           '-ms-transform': 'scale(' + val + ')',
           'transform': 'scale(' + val + ')',
           'transform-origin': 'left -10px',
           '-webkit-transform-origin': 'left -10px'               
         };
       }
     };
     
     scope.topBarStyle = function () {
       if (newValue.w > 890) { 
         return {};
       } else { 
         val = newValue.w/890;
         return {
           '-webkit-transform': 'scale(' + val + ')',
           '-o-transform': 'scale(' + val + ')',
           '-ms-transform': 'scale(' + val + ')',
           'transform': 'scale(' + val + ')',
           'transform-origin': '0 2px 0',
           '-webkit-transform-origin': '0 2px 0'  
         };
       }
     };
    }, true);

   w.bind('resize', function () {
     scope.$apply();
   });
  }
})

As you can see all the magic is done with transform:scale CSS attribute on the two of my main page components: the navigation and the contents container.

They styles are cross-browser.

return {
  '-webkit-transform': 'scale(' + val + ')',
  '-o-transform': 'scale(' + val + ')',
  '-ms-transform': 'scale(' + val + ')',
  'transform': 'scale(' + val + ')'             
}; 

It's important to set transform-origin, or the elements will be weirdly positioned on the page.

return {
  'transform-origin': '0 top',
  '-webkit-transform-origin': '0 top'                
}; 

The style calculations are attached to the changes of window dimensions.

scope.getWindowDimensions = function () {
  return {
    'h': $window.innerHeight,
    'w': $window.innerWidth
  };
};
scope.$watch(scope.getWindowDimensions, 
             function (newValue, oldValue) {
...
});

Few other things. My layout was sliced to the fixed width of 890px, that's why I took 890 as the pivotal point of my scale ratio formula. You should take the default width of the layout as the base of your calculation.

if (newValue.w > 890) {
  return {};
} else {
  val = newValue.w/890;
  return {
    '-webkit-transform': 'scale(' + val + ')',
  }
});

With the directive in place it's time to plug it in:

 
   
  

Be sure to use style "display:block" or "display:inline-block" and "position:relative" for all the inside components of the scaled elements with the default display. Otherwise they do not obey the scaling enforcement and grow way too long prompting a scrollbar.

It all worked nicely and I was able to enjoy the smoothly resizing layout.


Comments

published by noreply@blogger.com (Selvakumar Arumugam) on 2015-01-12 15:30:00 in the "AngularJS" category

This is the second part of an article about the conference Open Source India, 2014 was held at Bengaluru, India. The first part is available here. The second day of the conference started with the same excitement level. I plan to attend talks covering Web, Big Data, Logs monitoring and Docker.

Web Personalisation

Jacob Singh started the first talk session with a wonderful presentation along with real-world cases which explained the importance of personalisation in the web. It extended to content personalisation for users and A/B testing (comparing two versions of a webpage to see which one performs better). The demo used the Acquia Lift personalisation module for the Drupal CMS which is developed by his team.

MEAN Stack

Sateesh Kavuri of Yodlee spoke about the MEAN stack which is a web development stack equivalent to popular LAMP stack. MEAN provides a flexible compatibility to web and mobile applications. He explained the architecture of MEAN stack.

He also provided an overview of each component involved in MEAN Stack.

MongoDB - NoSQL database with dynamic schema, in-built aggregation, mapreduce, JSON style document, auto-sharding, extensive query mechanism and high availability.

ExpressJS - A node.js framework to provide features to web and mobile applications.

AngularJS - seamless bi-directional model with extensive features like services and directives.

Node.js - A server side javascript framework with event based programming and single threaded (non blocking I/O with help of request queue).

Sails.js - MEAN Stack provisioner to develop applications quickly.

Finally he demonstrated a MEAN Stack demo application provisioned with help of Sails.js.

Moving fast with high performance Hack and PHP

Dushyant Min spoke about the way Facebook optimised the PHP code base to deliver better performance when they supposed to handle a massive growth of users. Earlier there were compilers HipHop for PHP(HPHPc) or HPHPi(developer mode) to convert the php code to C++ binary and executed to provide the response. After sometime, Facebook developed a new compilation engine called HipHop Virtual Machine(HHVM) which uses Just-In-Time(JIT) compilation approach and converts the code to HipHop ByteCode(HHBC). Both Facebook?s production and development environment code runs over HHVM.
Facebook also created a new language called Hack which is very similar to PHP which added static typing and many other new features. The main reason for Hack is to get the fastest development cycle to add new features and release frequent versions. Hack also uses the HHVM engine.

HHVM engine supports both PHP and Hack, also it provides better performance compare to Zend engine. So Zend Engine can be replaced with HHVM without any issues in the existing PHP applications to get much better performance. It is simple as below:

Also PHP code can be migrated to Hack by changing the <?php tag to <?hh and there are some converters (hackficator) available for code migration. Both PHP and Hack provide almost the same performance on the HHVM engine, but Hack has some additional developer-focussed features.

Application Monitoring and Log Management

Abhishek Dwivedi spoke about a stack to process the logs with various formats, myriad timestamp and no context. He explains a stack of tools to process the logs, store and visualize in a elegant way.

ELK Stack = Elasticsearch, LogStash, Kibana. The architecture and the data flow of ELK stack is stated below:


Elasticsearch - Open source full text search and analytics engine

Log Stash - Open source tool for managing events and logs which has following steps to process the logs

Kibana - seamlessly works with Elasticsearch and provides elegant user interface with various types of graphs

Apache Spark

Prajod and Namitha presented the overview of Apache Spark which is a real time data processing system. It can work on top of Hadoop Distributed FileSystem(HDFS). Apache Spark performs 100x faster in memory and 10x faster in disk compare to Hadoop. It fits with Streaming and Interactive scale of Big Data processing.

Apache Spark has certain features in processing the data to deliver the promising performance:

  • Multistep Directed Acyclic Graph
  • Cached Intermediate Data
  • Resilient Distributed Data
  • Spark Streaming - Adjust batch time to get the near real time data process
  • Implementation of Lambda architecture
  • Graphx and Mlib libraries play an important role

Online Data Processing in Twitter

Lohit Vijayarenu from Twitter spoke about the technologies used at Twitter and their contributions to Open Source. Also he explained the higher level architecture and technologies used in the Twitter microblogging social media platform.

The Twitter front end is the main data input for the system. The Facebook-developed Scribe log servers gather the data from the Twitter front end application and transfers the data to both batch and real time Big Data processing systems. Storm is a real time data processing system which takes care of the happening events at the site. Hadoop is a batch processing system which runs over historical data and generates result data to perform analysis. Several high level abstraction tools like PIG are used write the MR jobs. Along with these frameworks and tools at the high level architecture, there are plenty of Open Source tools used in Twitter. Lohit also strongly mentioned that in addition to using Open Source tools, Twitter contributes back to Open Source.

Docker

Neependra Khare from Red Hat given a talk and demo on Docker which was very interactive session. The gist of Docker is to build, ship and run any application anywhere. It provides good performance and resource utilization compared to the traditional VM model. It uses the Linux core feature called containerization. The container storage is ephemeral, so the important data can be stored in persistent external storage volumes. Slides can be found here.


Comments

published by noreply@blogger.com (Brian Gadoury) on 2014-12-05 21:43:00 in the "AngularJS" category

Seeing the proposed line-up for the 2014 hack.summit() virtual conference was the grown-up equivalent of seeing the line-up for some of the first Lollapalooza events. It was definitely an "All those people I want to see, and all in one place? *head asplode*" moments.

So, what is this conference with the incredibly nerdy name? In short, it's a selection of industry leading speakers presenting all on-line and streamed live. The "registration fee" was actually a choice between mentioning the conference on a few social media platforms, or making a donation to one of a number of programming non-profits. Seeing as I don't tweet, I made a donation, then signed in (using OAuth) via my Google+ account. It was a delightfully frictionless process.

The hack.summit() conference ran December 1st through December 4th, but I was only able to "attend" the last two days. Luckily for me, all of the live-streamed presentations are also available afterwards on the hacksummit site. They feel a little hidden away in the small menu in the upper left corner, but they're all there, available as YouTube videos.

So, why is was hack.summit() worth your time? It's got an amazing collection of very accomplished developers, thought leaders and experienced big cheeses of some companies that do some pretty impressive work. During the live event, the Crowdcast platform provided a great delivery mechanism for the streaming videos, as well as admin-created polls, a light-weight chat feature, and audience-voted questions for the presenters. Hack.summit() founder, Ed Roman, did a great job MC-ing the entire event, too. (And to whoever figured out how to game the voting system at a conference named hack.summit(), well played you rogue.)

In closing, I strongly recommend you do a few things: Go sign up right now to gain access to the presentation videos. Commit some time (make a deal with yourself, get approval to do a group viewing at work, whatever) to watch as many presentations as you can. Lastly, set a calendar reminder to keep an eye out for the hack.summit() 2015 that will hopefully happen.


Comments