Montag, 14. Oktober 2013

uncomfortable pattern in emberjs

First of all ember is great I will use it. But there is one point I feel very uncomfortable with....
Embers url pattern to add delete, edit or create objects. In my opinion they are not restful.
The ember way  is a little bit like the soap way. And the soap way handling methods is not the restful way of the WEB
In Ember you define a resource and routes on this resource.

@resource "order", ->
           @route "edit"
           @route "new"

etc.

For example    someServer/orders/new   does not represent a resource in the restful way. It represents an action on the resource in this case orders.
In the restful way   CRUD is done via http verbs and not with explicit semantic action expressions in the url.
In my opinion there is a missfit between the ember way of routing  as absolute state and the way web works.
A single page application does not need any http verbs (it does not talk to the server for a longer period of time) except when synchronizing with the server.   But from the absolute point of view (A user does not know wether it is a single page app or many  pages with request responses) there must be something else for the http verbs.  But what ?
If there is a semantic in the url and not only state : Does bookmarking of the delete action of a resource make sense ?  Is it  (REST)web conform ?

Lets think a little bit more far:   Suppose ember would also run on the server (just think very modular - no output no templates - just logic) .  Then a delete of a record is not done with one of the http verbs but done with an explicit call of a method. Then You do not need any http verbs just posts like soap right ?





I have tried to implement a restful way in my emberplayground at github. All methods are in the controller, from there the view are triggered.
Perhaps there are other problems with this solution but the url does not show any semantic methods like edit or new.

https://github.com/erhard/emb_boot/tree/controlleractions

Donnerstag, 19. September 2013

clientside loadbalancing

The situation in many cases is that loadbalancing happens on the web-server.
A typical J2EE application has apache as loadbalancer in front of  more servers. Each request comes to apache and is forwarded to one of those servers. 
There a a lot of topologies how this clusters can be designed. Or even hardware solutions are common to balance the incoming requests.
(http://stackoverflow.com/questions/12526265/loadbalancing-web-sockets). Loadbalancing is a very complex and deeply discussed topic.

This post explains a very simple and robust way of loadbalancing in Rich Internet Applications (single page applications).

The solution is based on jsonp (http://en.wikipedia.org/wiki/JSONP) which allows requests to other servers.

The idea is to have a small footprint page which loads the rest via jsonp from a server choosen by chance from a list of servers.

So here we go in coffeescript

Define a list of servers

root.servers    = ["http://localhost:45567/","http://localhost:4567/","http://localhost:45567/" ]




In the following class a server is choosen by chance. If the server is not available another server of the list is choosen. Only If all servers are not available a message to the user is shown.

With this technique not only loadbalancing can be done also failover and setting up new versions without downtime can be implemented.



class root.ServerTools

 @delete_element_from_array: (element_to_delete,array) ->
    for element, i in array
           if (element == element_to_delete)
               array.removeAt(i, 1)
    return array
  
  @doAjax: (path, slist,  timeout, dfd) ->
        slist    || (slist = root.servers)
        dfd      || (dfd = $.Deferred())
        timeout  || (timeout = 2000)
        #Timeout is because of javascript issue with jsonp requests Stackoverflow - question 10093497
        index=Math.floor(Math.random()*slist.length)
        current_element = slist[index]
        url=current_element + path
        args = {url: url, type: "GET", dataType: "jsonp", timeout: timeout}
        $.ajax(args).then(dfd.resolve, \
           (xhr, text_status, error_thrown) ->
                console.log error_thrown
                slist=root.ServerTools.delete_element_from_array(current_element,slist)
                if(slist.length == 0)
                   dfd.reject(xhr, text_status, error_thrown)
                else
                   root.ServerTools.doAjax(path, slist, timeout, dfd)
        )
        return dfd.promise()

 call the promise :

      promise = root.ServerTools.doAjax("orders.jsonp", root.servers,2000 )
      promise.done (response) ->   (App.Order.transform_response_to_orders(response))
      promise.fail -> alert("no Server reachable - please try later again")




Here is the complete example:


checkout  https://github.com/erhard/emb_boot.git

sha 4cb020f3a5


You need ruby or jruby and the sinatra gem.
Start the sinatra server in bin
It servers the jsonp data and the static index.html
Go to your browser and choose localhost:4567
Now the footprint is loaded and in addition from the serverlist above (where only the port 4567 is available) the dynamic rest. The kick is that the servers do not need to be on the same maschine as the page.