Baratine on GitHub

Baratine 0.10

Baratine 0.10.3 - 2015-12-11

WebSocket for Baratine in Servlet Web-App

Baratine now supports websockets when it is Baratine is deployed in WEB-INF/lib/baratine.jar.

Dependency Cleanup/Removal

Several JavaEE dependencies have been removed from Baratine, including CDI and javax.el. baratine.jar is now below 7.5M.

Maven Repository for baratine-js

<dependency>
  <groupId>io.baratine</groupId>
  <artifactId>baratine-js</artifactId>
  <version>[0.10.2,)</version>
</dependency>

Maven Archetype for Baratine

$ mvn archetype:generate \
      -DarchetypeGroupId=io.baratine \
      -DarchetypeArtifactId=baratine-maven-archetype \
      -DarchetypeVersion=0.10.3 \
      -DgroupId=echo \
      -Dpackage=echo \
      -DartifactId=pod \
      -DinteractiveMode=false

The archetype includes a single-page application for an echo service.

Building and running in maven looks like the following:

$ mvn package baratine:run

Result.newFork changes

Result.newFork() - fork/join is used for parallel async requests. When all the parallel branches complete, a join function is called to calculate the final results.

The new method creates a builder.

  • create new branches with builder.fork()
  • join the branches with builder.join(function)
  • or join with builder.join(BiConsumer<X,Result<T>> consumer)
public void doStuff(Result<String> result)
{
  Result.fork<String,String> fork = result.newFork();

  _serviceA.doRequest("arg1", fork.fork());
  _serviceB.doRequest("arg2", fork.fork());

  fork.join(values->processValues(values));
}

public String processValues(List<String> values)
{
  return String.valueOf(valuese);
}

Baratine 0.10.2 - 2015-11-12

.war integration

Baratine can now be deployed in servlet containers by adding baratine.jar to WEB-INF/lib. When the web-app starts, it creates a ServiceManager, scans the WEB-INF jars and classes for @Service classes, and binds them to the manager.

WEB-INF/classes/test/MyServiceImpl.java:

@Service("/test")
public class MyServiceImpl
{
  public void test(Result<String> result)
  {
    result.complete("hello");
  }
}

WEB-INF/classes/test/MyServlet.java:

@Override
public void init(ServletContext cxt)
{
  ServiceManager manager = ServiceManager.current();

  _myService = manager.lookup("/test")
                      .as(MyServlet.class);
}

The .war integration has been tested on Resin 4, Tomcat and Jetty. The testing has been fairly minimal.

Jamp servlet

The Jamp REST servlet is also available as:

com.caucho.v5.jamp.JampServlet

If the service is public, using “public:///test”, the REST will be available as http://localhost:8080/jamp/test?m=test.

For 0.10.2, only REST and application/jamp-rpc are available.

Notes on the .war integration

The internal changes for the .war integration are fairly significant, particularly related to the scanning and @Inject support. Prior to this change, Baratine could rely on its internal CDI implementation and servlet support. Decoupling from that dependency is partial in 0.10.2. More work will be required for 0.10.3.

OpenSSL

The HTTP port can be configured to use SSL. The configuration looks like the following:

cluster {
  server-default {
    openssl {
      certificate-file "keys/gryffindor.crt";
      certificate-key-file "keys/gryffindor.key";
      password "my-password";
    }
  }

  server "10.0.0.10" 6810;
}

Baratine 0.10.1 - 2015-09-23

ServiceManager

Changed method name to current():

manager = ServiceManager.current();

Added newManager to create an embedded manager:

manager = ServiceManager.newManager().build();

Added setSystemExecutorFactory for integration, specifically for integration with vert.x.

The executor factory is used when calling Baratine from an external Java context. It supplies the executor for a result. By default, Baratine will spawn a thread for a response. In the case of a reactor model like vert.x, this allows the reply to be passed to the vert.x context reactor.

@Journal

The default journal behavior is now to send an @OnSave in the afterBatch. This means that saves behave the same as in the non-journal case.

The new attribute @Journal(delay=120000) customizes this behavior. With a delay, the @OnSave will only be called after the delay timeout, which can increase batching efficiency.

BFS watch/CancelHandle

The BfsFile.watch method now returns a CancelHandle for unregistering a watch.

Baratine 0.10.0 - 2015-08-06

ResultStream/ResultStreamBuilder

The new ResultStream and ResultStreamBuilder are a redesign of the streaming API. As before, ResultStreamBuilder is used by the proxy API, and ResultStream is by the implementation.

ResultStreamBuilder has now only two terminals, exec and result, which start the stream. All other methods, such as reduce, collect, and forEach are stream filters, and no longer terminals.

A typical use is from the Lucene example:

_reader.search(collection, query)
       .collect(ArrayList<LuceneEntry>::new,
                (list, entry) -> list.add(entry),
                (listA, listB) -> listA.addAll(listB))
       .result(result);

The collect gathers results from each node into a list. If there are multiple lists, they are combined by the caller. Finally, the result is returned to the async result of the search method.

ResultStream cancel/isCancelled

ResultStream can now be used as a message-based subscription API with the addition of cancel/isCancelled. A pub/sub broker can test for cancelled or disconnected subscriptions by calling isCancelled. Session services can also use the result stream to allow for client streaming.

JAMP stream

JAMP streaming messages are now added to support client streaming.

["stream", {}, "/from", 13, -1, "/to-service", "to-method", arg1, ..., argN]
["stream-result", {}, "/from", 13, [value1, ..., valueN]]
["stream-complete", {}, "/from", 13]
["stream-cancel", {}, "/from", 13]

javax.script embedding

Embedded applications can now use javax.script to start an embedded server. The script statements are Baratine CLI commands, as in the Baratine scripting.

This javax.script interface allows embedding applications to avoid dependencies on the Baratine API.

manager = new ScriptEngineManager();
engine = manager.getEngineByName("baratine");
engine.eval("start -bg -d /tmp/baratine -p 8085");
...
engine.eval("shutdown");

ServiceClient

The Java client has a new standard interface.

String url = "http://localhost:8085/s/pod";
ServiceClient client = ServiceClient.newClient(url).build();

MyService service = client.lookup("remote:///service")
                          .as(MyService.class);

RPC/jamp-rpc performance improvements

While async calls are still faster than RPC calls, the RPC performance is now much closer. Now, async calls were about 7m calls/sec and RPC calls around 3m calls/sec.

Remote jamp-rpc calls are faster than before at around 1m calls/sec.

JAMP HTTP

The JAMP /s/pod calls are now only valid for a server that has an active node for the pod. If the current server does not have an active node for that pod, a HTTP redirect occurs to the appropriate server.

Any pod forwarding needs an application facade for the given server; Baratine will no longer automatically forward, for security reasons.

TCP dual port

Baratine now uses a distinct port for internal cluster messages. The public port is only used for the JAMP requests and for information about the internal port. The dual port architecture simplifies security by making it easier to firewall the internal ports.

ServiceManager API changes

Now has a static getCurrent() method to get the current ServiceManager.

newService() returns a builder for creating a new service.

ServiceRef API changes

Now has a getCurrent() method to return the current ServiceRef.

pin() is the new method name to pin a listener/callback to the service’s inbox.

flushOutbox and flushOutboxAndExecuteLast are new static methods. These are generally used internally or for testing.

getServiceRef returns the ServiceRef for a proxy.

isClosed tells if the ServiceRef is to an active service.

CLI “package” command

The package command creates an executable jar that includes an application .bar or .jar file and embeds Baratine. The jar uses the same CLI commands as Baratine. On a “start” command, it will automatically deploy the embedded application.

$ bin/baratine package -o my-jar.jar my-app.bar
$ java -jar my-jar.jar start
$ java -jar my-jar.jar shutdown

subscribe/consume now return CancelHandle

The CancelHandle is now used to unsubscribe, which simplifies registration/unregistration of lambda callbacks.

Timer API changes

CancelHandle now used to unregister timers.

The timer callback is now a Consumer<CancelHandle>, which allows the timer to cancel itself.

timer.runEvery(handle->doTimer(handle), 1, TimeUnit.HOUR, Result.ignore());

Pod assignment

Pod assignment is visible in /config/pods/20-autopod.cf. Internally, a system service creates that pod configuration file whenever the topology changes.

With this change, all the pod topology is contained in the /config/pods files, with the single exception of the cluster_hub pod.

User Example

An User example using Baratine is now available to show a simple CRUD application.

See Baratine User.