WebSockets with Grails

Last week I had an interesting discussion about how to relief a threaded application server’s burden. When clients regularly poll the application server with a certain time window, just to ask whether there are updated information available, every time a server thread is opened. With many clients connecting simultaneously to the server the server’s thread pool can be exhausted, causing a halt to the application.

While there are non-blocking servers on the market, often you cannot easily switch your server product or change the overall application architecture to a message driven architecture.

Therefore, one possible architectural solution we discussed, was the concept of WebSockets.

The HTML5 Websocket specification defines a full duplex two-way communication between client and server over a single connection. Two-way communication means, that with WebSockets a server is able to push a message out to its clients. In consequence, a given threaded server can serve more clients or support more concurrent connections.

Don’t be misleaded by the word WebSocket. WebSocket is not a socket technique like you might know from your unix system, WebSocket is a protocol. The WebSocket starts as an ordinary http connection (http://), but then asking the server that it want to switch to the WebSocket protocol (ws://). If this request is granted, the http connection breaks down and is replaced by a WebSocket connection over the same underlying TCP/IP connection. The WebSocket uses port 80 or 443. Now, the communication packets can be sent  back and forth between client and server. They even travel through proxies and firewalls, which eases the application development a lot.

Let us see, how we can make use of WebSockets with Grails.

This demonstrator sends the server’s cpu load to a client’s web browser. On the server side exists a service SimpleMessagingService, which measures the cpu load every 5 seconds. The result is put into a topic queue “topic/cpuLoad”. Over the WebSocket protocol the queue’s content is pushed out to the browsers of all clients, who are subscribed to this topic queue. All subscribed browsers are updated all most simultaneously.

WebSocketBrowser

A very nice WebSocket plugin exist for Grails. It makes the integration of Spring 4.0 WebSocket support a breeze. Just add compile “:spring-websocket:1.3.0″ to the plugins section of Grails BuildConfig.groovy.

With Spring 4.0 WebSocket there are various possibilities to send or receive message. Here I will use the SimpMessagingTemplate and its convertAndSend function.

SimpleMessagingService.groovy

package com.jolorenz

import org.springframework.messaging.simp.SimpMessagingTemplate
import java.lang.management.ManagementFactory;

import com.sun.management.OperatingSystemMXBean;
import grails.transaction.Transactional
import groovy.json.JsonBuilder

@Transactional
class SimpleMessageService {

   SimpMessagingTemplate brokerMessagingTemplate
   OperatingSystemMXBean bean = (com.sun.management.OperatingSystemMXBean)   
   ManagementFactory.getOperatingSystemMXBean()

   void systemCpuLoad() {

      def cpuLoad = bean.getSystemCpuLoad()
      cpuLoad = (cpuLoad*100).round(2)

      def builder = new JsonBuilder()
      builder {
         message("CPU system load: " + cpuLoad + "%")
         timestamp(new Date())
      }
      def msg = builder.toString()
      brokerMessagingTemplate.convertAndSend "/topic/cpuLoad", msg
   }
}

Next, we need a html/javascript page with the corresponding topic queue, e.g. “/topic/cpuLoad”.

index.gsp

<!DOCTYPE html>;
<html>;
   <head>;
   <meta name="layout" content="main" />
   <asset:stylesheet src="application.css" />
   <asset:javascript src="application.js" />
   <asset:javascript src="jquery" />
   <asset:javascript src="spring-websocket" />

   <script type="text/javascript">
      $(function() { 
         //Create a new SockJS socket - this is what connects to the server
         //(preferably using WebSockets).
         var socket = new SockJS("${createLink(uri: '/stomp')}");

         //Build a Stomp client to send messages over the socket we built.
         var client = Stomp.over(socket);

         //Have SockJS connect to the server.
         client.connect({}, function() {             
            client.subscribe("/topic/cpuLoad", function(message) {
               var msg = JSON.parse(message.body)
               var time = '<strong>;' + new Date(msg.timestamp).toLocaleTimeString() + '</strong>'
               $("#cpuLoadDiv").append(time + ': ' + msg.message + "<br/>");
            });
         });                
      });
   </script> 
</head>

<body>
   <div id="cpuLoadDiv"></div>
</body>
</html>

Indeed, this is all what is needed to establish a WebSocket communication between server and client. Yes, it is a simple example and lacks features like filters for user groups or security, but it gives you an idea to become familiar with WebSockets.

What are the Cons?
WebSocket is a browser feature and not all browsers support this feature. Probably in the near future, all browsers and servers will support WebSockets.
CanIUse provides a good overview of the supported web browsers.

Browser with WebSocket Support

WebSocketSupport

WebSockets are a suitable technique, but what if the browsers of my audience do not support it yet?
Just in case, falling back to “Long Polling” is a workaround to get effectively the same behavior.
Long Polling is not as efficient but it works nicely. Bear in mind, that your web frameworks should gracefully fallback to use Long Polling when Web Socket is not available.

HTH Johannes

Related readings:

Posted in Development | Tagged , , | Leave a comment

Java CSV-Parser Comparison on Github

There are quite a few Java CSV parsers available. If you are unsure which one to choose or you wonder how they perform, have a look at github.

There is a project to do performance testing of various CSV parsers.

If you don’t like to do the testing, there are also charts with the results depending on the JDK version.

Personally, I use the Jackson CSV library, which achieved quite good results in the  tests.

HTH Johannes

Posted in Development, Java | Tagged , | Leave a comment

Install the AVR Toolchain on OS X

Programming AVRs or Arduinos is easy and convenient with the Arduino IDE. On the one hand side, the high-level Arduino libraries hide a lot of complexity and you get your results probably faster, but on the other side the concept of high-level libraries results in bloated hex-files.

If you program small or cheap AVR MCUs, these hex files might not fit in the flash.  And in the end, the Arduino IDE is basically a text editor with some syntax coloring. Therefore I prefer to program against the avr-libc with the  support of a powerful IDE like Eclipse. Here are the steps to install this AVR toolchain on OS X:

1. Download the AVR toolkit from the Cross Pack website: www.obdev.at/products/crosspack/

2. Save the disk image

3. Run the disk image (dmg) and install the toolkit.

4. Open a terminal window and check the installation:

cd /usr/local/CrossPack-AVR-20131216/bin
avr-gcc --version

should respond to:

avr-gcc (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

While some people are completely satisfied to program the AVR firmware with vi, some C source files, avr-gcc and make, I prefer a fully fledged and convenient IDE.

6. Download and install the Eclipse C++ IDE

7. Install the AVR-Eclipse plugin by opening inside Eclipse the Help -> Install New Software menu. In the opened window, enter AVR Eclipse Plugin and http://avr-eclipse.sourceforge.net/updatesite/, press enter and select in the lower window the AVR Eclipse Plugin. Click Next, answer all questions with yes, wait until the installation is finished, ignore the warning about unsigned software and restart Eclipse.

8. Configure AVRDude: click Eclipse -> Preferences -> AVR menu. Check the Paths settings and if these are correct click AVRDude -> Add to configure avrdude and the appropriate programmer.

9. Now you are ready and prepared to program your first AVR project. Select New -> Project -> C-Project and the wizard will guide you and perform the initial setup of your project.

HTH Johannes

Posted in Embedded Development, IoT | Tagged , , , | Leave a comment

How to install Groovy on a Banana Pi or Raspberry Pi

The Raspberry or Banana Pi have already pre-installed Python.
If you like to stay with Groovy on these nice little devices, here are the instructions to install Groovy.
GVM makes the whole process very easy and convenient.

Open a terminal window and use these commands:

curl -s get.gvmtool.net > installGroovy.sh
chmod u+x installGroovy.sh
installGroovy.sh
source “$HOME/.gvm/bin/gvm-init.sh”
gvm install groovy

This will download and install the latest Groovy version.
Check the installed version:

groovy -version
Groovy Version: 2.4.2 JVM: 1.8.0 Vendor: Oracle Corporation OS: Linux

Happy Groovy coding on your Banana Pi,
Johannes

Posted in Development, Groovy | Tagged , , , , | Leave a comment

Adaptive machine learning in a streaming environment

Here is a very nice explanation about adaptive machine learning in a streaming environment.

Adaptive machine leaning

Posted in Big Data | Tagged , , | Leave a comment

How to Solve: “Too many connections”; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:

Hi,

in one of my projects I used GPars and its withPool() method to execute some async tasks.
The prime purpose of a task is to fetch some data from external sources and save the resulting data to a database. Very simple.

While the task did not consume much memory and the performance was mostly determined by the response time of some external rest services, I used quite a high parallelism with a pool size of 500.

// GPars
withPool(500) {
   tasksToDo.eachParallel { task ->
      // .. do some long running tasks asynchronously
      // and save the result to a database 

   }
}

Everything worked fine in the local Grails test environment.
As production environment I used Amazon’s AWS beanstalk and a RDS mysql instance as database backend, both as t1.small instances.

But with the Amazon installation i got the following error message:

"Too many connections"; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:

2014-08-20 09:19:54,373 [ForkJoinPool-1-worker-218] ERROR crawler.BasicRssGatherer  - org.springframework.dao.DataAccessResourceFailureException: Hibernate operation: could not prepare statement; .....
.....
Data source rejected establishment of connection,  message from server: "Too many connections"

It turned out, that Amazon RDS instances have a fixed limit of available connections.
You can check this out, by

  • opening the AWS console,
  • go to your RDS instance,
  • open “Parameter Groups” and
  • seek for “max_connections”.

In my case the formula found is: {DBInstanceClassMemory/12582880}, which calculates to:

	 * MODEL      max_connections innodb_buffer_pool_size
	 * ---------  --------------- -----------------------
	 * t1.micro   34                326107136 (  311M)
	 * m1-small   125              1179648000 ( 1125M,  1.097G)
	 * m1-large   623              5882511360 ( 5610M,  5.479G)
	 * m1-xlarge  1263            11922309120 (11370M, 11.103G)
	 * m2-xlarge  1441            13605273600 (12975M, 12.671G)
	 * m2-2xlarge 2900            27367833600 (26100M, 25.488G)
	 * m2-4xlarge 5816            54892953600 (52350M, 51.123G)

It is not possible to adjust these settings. So you can either switch to a bigger and more costly RDS instance, or reduce the pool size, which might reduce the overall performance of your app. This might be Amazon’s approach of monetarization. A third option is to roll out your own mysql installation, where you can set the connection limit by yourself, but you will loose all opportunities of a managed RDS database.

So, be aware that Amazon’s RDS mysql instances have a fixed connection limit, if you are working with high numbers of parallel database accesses. The limit can be calculated by the formula found in the max_connection section as DBInstanceClassMemory/12582880.

HTH
Johannes

Posted in Development | Tagged , , | 1 Comment