A few months back I wrote some code to compute a moving average (well more accurately it's a moving window of a counter). This implementation was functional, yet not particularly efficient. The main problem was it required a thread per metric. Recently I updated the code to share a thread; it is described on github.
Friday, February 14, 2014
Saturday, January 18, 2014
Deploying a Play Framework Application on Raspberry Pi
It's simple to deploy a playframework application, just run 'play dist' and move the appname-version-SNAPSHOT.zip to your server, unzip and run the bin/appname script
However, the script's default memory allocation is 1GB, which more than a Raspberry Pi can support, and leads to the following error:
BTW, I'm running Java 7 for ARM
However, the script's default memory allocation is 1GB, which more than a Raspberry Pi can support, and leads to the following error:
Error occurred during initialization of VM Could not reserve enough space for object heap
BTW, I'm running Java 7 for ARM
java -version java version "1.7.0_10" Java(TM) SE Embedded Runtime Environment (build 1.7.0_10-b18, headless) Java HotSpot(TM) Embedded Client VM (build 23.6-b04, mixed mode)
Reading through the script you'll see there are several options you can pass, including a mem option
bin/appname -h Usage: [options] -h | -help print this message -v | -verbose this runner is chattier -d | -debug set sbt log level to debug -memset memory options (default: , which is -Xms1024m -Xmx1024m -XX:MaxPermSize=256m -XX:ReservedCodeCacheSize=128m) -jvm-debug Turn on JVM debugging, open at the given port. # java version (default: java from PATH, currently java version "1.7.0_10") -java-home alternate JAVA_HOME # jvm options and output control JAVA_OPTS environment variable, if unset uses "" -Dkey=val pass -Dkey=val directly to the java runtime -J-X pass option -X directly to the java runtime (-J is stripped)
I changed the memory to 32mb and it started just fine
bin/appname -mem 32
bin/appname -mem 32 Play server process ID is 4356 [info] play - datasource [jdbc:postgresql://192.168.1.15:5432/postgres] bound to JNDI as DefaultDS [info] play - database [default] connected at jdbc:postgresql://192.168.1.15:5432/postgres [info] application - Application has started [info] play - Starting application default Akka system. [info] play - Application started (Prod) [info] play - Listening for HTTP on /0.0.0.0:900
Wednesday, January 15, 2014
Optimistic Locking and Timestamp Precision with Ebean and Postgres
Lately I've been experimenting with the Play Framework. I'm using Avaje Ebean (JPA), the default ORM for Play Framework, with Postgres. I have an Akka background task that kicks off search jobs. To force a job to run I can simply change the run-at field
update search set next_run_at = now()
But I found this results in an OptimisticLockException when the scheduler runs:
update table set ... where next_run_at = "2014-01-15 08:18:08.518000"
but the field has microsecond precision: "2014-01-15 08:18: 08.518337" so it fails to update
There are a few solutions to this problem. One solution is to be mindful of SQL updates to timestamps that occur outside of your application and only use only millisecond precision. For this I found the date_trunc Postgres function:
date_trunc('milliseconds', now())
Another option is to set the precision of the timestamp field to milliseconds
ALTER TABLE ... next_run_at timestamp(3)
You might think you'd just turn off optimistic locking if you don't need it, but it appears that it is not possible to do so with Ebean.
Another possible solution is to use the @Version JPA Annotation. With @Version, Ebean will only include the version field to determine perform optimistic locking
update search set next_run_at = now()
But I found this results in an OptimisticLockException when the scheduler runs:
javax.persistence.OptimisticLockException: Data has changed. updated [0] rows sql[update search set next_run_at=?, last_run_at=?, run_count=? where id=? and name is null and search=? and low is null and high is null and exact_match=? and active=? and notify_immediately=? and scheduled=? and frequency_hours=? and search_date is null and next_run_at=? and last_run_at=? and created_at=? and updated_at is null and error_count=? and result_count=? and run_count=? and location=? and account_id=?] bind[null]
at com.avaje.ebeaninternal.server.persist.dml.DmlHandler.checkRowCount(DmlHandler.java:95) ~[avaje-ebeanorm.jar:na]
at com.avaje.ebeaninternal.server.persist.dml.UpdateHandler.execute(UpdateHandler.java:81) ~[avaje-ebeanorm.jar:na]
at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:86) ~[avaje-ebeanorm.jar:na]
at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.update(DmlBeanPersister.java:66) ~[avaje-ebeanorm.jar:na]
at com.avaje.ebeaninternal.server.persist.DefaultPersistExecute.executeUpdateBean(DefaultPersistExecute.java:82) ~[avaje-ebeanorm.jar:na]
at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeNow(PersistRequestBean.java:452) ~[avaje-ebeanorm.jar:na]
It turns out that Ebean uses optimistic locking by default. This works by updating the row only if none of the columns changed since the initial select query. The problem occurs since my POJO uses the Java Date class, which provides only millisecond precision and the Postgres now function provides microsecond precision (an additional 3 digits). This results in a loss of precision and the fields don't match so Ebean thinks another process updated the fields. For example, the Ebean update statement looks likeupdate table set ... where next_run_at = "2014-01-15 08:18:08.518000"
but the field has microsecond precision: "2014-01-15 08:18: 08.518337" so it fails to update
There are a few solutions to this problem. One solution is to be mindful of SQL updates to timestamps that occur outside of your application and only use only millisecond precision. For this I found the date_trunc Postgres function:
date_trunc('milliseconds', now())
Another option is to set the precision of the timestamp field to milliseconds
ALTER TABLE ... next_run_at timestamp(3)
You might think you'd just turn off optimistic locking if you don't need it, but it appears that it is not possible to do so with Ebean.
Subscribe to:
Posts (Atom)