mercredi 20 mai 2009

GraniteDS 2.0 now supports server push on Google App Engine

We are close to releasing GraniteDS 2.0 RC1, hopefully the last release before GA. It includes a big refactoring of the Gravity core to simplify the implementation of new providers, and in particular there is a new Gravity provider for Google App Engine based on Memcache.

An example of this Google App Engine push implementation is available at http://gdsgaepush.appspot.com, once again with admin/admin or user/user. If you open two browsers on the application, the changes made on from side should be also updated on the other. The eclipse project can be downloaded here.

The GAE environment is very interesting because it is fully clustered: each request can be unpredictably handled by a different server instance. The only reliable way to communicate between different requests/users is by using the datastore or memcache (or a combination of both). In a first messaging implementation, we have chosen the memcache API that allows fast communication between processes and is easy to use. The main drawback is that it is not a reliable store and that client subscriptions or messages could be lost under high memory usage, but for non critical use it might be acceptable.

The implementation is relatively simple: Gravity subscriptions and channels are stored in the cache with a configurable expiration delay. Each channel maintains its current number of pending messages in the cache. Publisher threads just increment this number and store new messages in the cache, and subscriber threads poll the channel counter at regular intervals and get existing messages from the cache when there are available. The poller thread by default polls the channel every 500ms and has a total duration of 20s (under the 30s limit of GAE).

It's important to note that due to the use of memcache, only serializable objects can be sent in Gravity messages (but it's also the case with JMS). Besides that simple limitation, all features of Gravity (client <-> client, server -> client, selectors, ...) can be used with GAE (see documentation here).

The configuration of the GAE provider can be done as follows :

  • Define the Gravity GAE servlet in WEB-INF/web.xml :
  • <servlet>
    <servlet-name>GravityServlet</servlet-name>
    <servlet-class>org.granite.gravity.gae.GravityGAEServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>GravityServlet</servlet-name>
    <url-pattern>/gravityamf/*</url-pattern>
    </servlet-mapping>

  • Setup the GAE Gravity factory in WEB-INF/granite/granite-config.xml :
  • <gravity 
    factory="org.granite.gravity.gae.GAEGravityFactory
    channel-idle-timeout-millis="1800000">
    <configuration>
    <gae polling-interval="500">
    </configuration>
    </gravity>

  • Finally define the GAE service adapter in WEB-INF/flex/services-config.xml :
  • <service id="gravity-service"
    class="flex.messaging.services.MessagingService"
    messageTypes="flex.messaging.messages.AsyncMessage">
    <adapters>
    <adapter-definition id="gae" class="org.granite.gravity.gae.GAEServiceAdapter"/>
    </adapters>

    <destination id="exampleDestination">
    <channels>
    <channel ref="my-gravityamf"/>
    </channels>
    <adapter ref="gae"/>
    </destination>
    </services>

    This new server push provider complements the current existing support for AMF remoting and JDO persistence and makes GraniteDS 2.0 a complete platform for deploying Flex applications on Google App Engine.

    As always, feedback and comments are welcome.

    8 commentaires:

    Roger a dit…

    i downloaded the eclipse project but it keeps complaining with this error:

    Type was not found or was not a compile-time constant: Key.

    On these two files:
    TaskBase.as
    TaskHistoryBase.as


    I am using eclipse Version: 3.4.2 with the granite builder plug in v 2.0.0.B2.

    Any ideas?

    William Draï a dit…

    The GAE Key classes is correctly translated to AS3 String only since the 2.0.0.RC1 granite builder plugin.

    Romain a dit…

    Hi,

    You did a great job, thank you!
    Just a question: as I need to minimize the SWF size, I wonder if can remove some stuff of the SWC that I do not use.
    I just want to use the concept of Producer/Consumer, I do not use Spring, EJB... do I need all the Tide classes?

    A1programmer a dit…

    How many simultaneous users will this support? I'm interested how this is getting around the limit of max concurrent connections on GAE. Also, are the 500ms polling intervals causing a lot of memcache and or http quota usages?

    Aaronius a dit…

    Thanks for the work you're doing with GraniteDS. I'm getting spotty success though.

    When I pull up your demo (http://gdsgaepush.appspot.com/), log in as an admin, then post a new task, sometimes it never gets added to its own datagrid.

    If I then re-load the app and re-log-in, the task will sometimes be there and sometimes not.

    I used the demo project and successfully deployed it as my own google app and got the same spotty results. It just seems like the messaging isn't very reliable.

    Any ideas or thoughts?

    Unknown a dit…

    You must be Santa. I've been looking for a push solution for month. Merci :)
    As A1programmer asked, any idea how many simultaneous users will this support?

    Unknown a dit…

    well we are really happy for upcoming apps!

    Server Support

    Unknown a dit…

    Thanx for sharing....
    Stone supplier