Wednesday, April 08, 2009

Terracotta, Domain Driven Design and Anti-Patterns

Yesterday I was going to participate at a technical meeting, when the following statement suddenly appeared on my Twitter timeline:

One interesting reflection is that the "super static" property of Terracotta roots helps us with Domain Driven Design.
Finally we have (what I feel a nice) way of using Repositories in our Entities without Aspects or Register style coding.


My immediate reaction was to reply by saying:

Strongly disagree. That means your business/domain code depends on Terracotta semantics.


I thought my comment were pretty intuitive: if Terracotta is a transparent clustering solution (and it actually is), how can Terracotta help you writing your domain code without polluting the code itself?

Too bad, I was wrong: it generated a lot of discussions with a few of my favorite tech-friends, and what's worse, I wasn't able to further clarify my statement!

Let me blame Twitter 140-characters constraint, please ... I don't want to hurt my own self-respect ;)

So here is a simple-stupid sample, which I hope will clarify the following simple concept: if your code relies on Terracotta super-static variables to access repositories (as apparently stated by the first quote above), then your code is IMO wrong.

Let's go.

We have an Amazon-style application, dealing with a lot of users and books: so we choose to use Terracotta for transparently clustering our application and make it scale.
Taking a deeper look at our domain, and using the Domain Drive Design terminology, we have two aggregate roots: User and Book.


public class User {

private final String id;

// ...
}

public class Book {

private final String isbn;

// ...
}


They're two separated roots because completely independent and with different lyfecycles.
So we have two different repositories, too:


public class UserRepository {

public User findById(String id) {

//...
}

// ...
}

public class BookRepository {

public User findByIsbn(String isbn) { //... }

// ...
}


Now, we want to add the following responsibility to our User: tell us all books he viewed.


public class User {

private final String id;

// ...

public Collection getViewedBooks() { //... }
}


We don't want to establish a permanent relation between User and Book, i.e., make the collection of viewed books an instance variable of user: it would clutter the User entity, and associate it a lot of additional data which is related to the user, but in no way part of the user itself.
So we choose to access Book entities through the BookRepository, meaning that User entities must have access to the repository instance.

The repository is implemented as a collection of objects persisted and distributed by Terracotta, so the following idea comes to our mind: we may configure the repository as a Terracotta root, and access its instance everywhere in our cluster of User objects thanks to its super-static nature!

For those unfamiliar with Terracotta, a Terracotta root, also known as super-static variable, is an object instance shared among all cluster nodes: it is actually created only the first time the new operator is called. After that, that instance will be always the same among all nodes, and every other new invocation will have no effect.

It means that we have a number of super-easy ways to access our super-static repository from inside our User entity, and here is one:


public class User {

private static final BookRepository bookRepository =
new BookRepository();

private final String id;

// ...

public Collection getViewedBooks() {
for (String isbn : viewed) {
Book book = bookRepository.findByIsbn(isbn);
}
// ...
}
}


Thanks to Terracotta, the BookRepository will be actually created for the first time, and then always reused, even if we shutdown our application and restart: the bookRepository persisted/distributed state will be always there.

Well, this is IMHO an anti-pattern.

While it is true that Terracotta makes easy to access repositories from entities, it is IMO wrong because coupled to Terracotta itself: if you swap out Terracotta, that static variable will be always reset at every shutdown/restart, as you would expect in any Java application, and your data will be gone!

I hope it's clearer now.
And if someone disagrees, or just thinks I misled the original quote, I'd be more than happy to hear his thoughts.

Finally, a disclaimer.
I'm an happy Terracotta user, and there are many ways to correctly use Terracotta in your application: putting it simple, just hide the way it works behind the repository implementation, and access the repository itself as it were a normal Java object, not a super-static one.

And that's all.

Tuesday, February 03, 2009

Actor concurrency model in a nutshell

While the necessity of writing software applications capable of exploiting the multi-processor architecture of today computers is more and more common, concurrent programming is often perceived as an hard task.
No wonder, so, if many languages come to our rescue by supporting concurrent programming through first-class syntax support, or through higher level user libraries.
Two well-known languages providing explicit concurrent programming support are Erlang and Scala, and both have in common the same concurrency model: actors.

The actor model is a concurrency abstraction based on the concepts of message-passing concurrency: very different from the shared state concurrency model we're used to in general purpose languages such as Java, but more efficient and easier to program with.

Let's see the difference between the two.

Shared-state concurrency is based on two fundamental concepts: resource sharing and resource synchronization.
As already said, it's the most common scenario with general purpose OO languages such as Java: it's composed by computational units (often implemented as threads) concurrently executing code sections containing resources that must be shared, and hence, synchronized in order to guarantee correct ordering, visibility and data consistency.

Message-passing concurrency, also known as share-nothing concurrency, is the exact opposite: here, computational units are just endpoints exchanging immutable messages one another, and reacting to received messages by executing a given computation.
In such a concurrency model, so, there isn't any shared resource, nor there is any need for resource synchronization: messages are immutable, and each computational unit is only able to change its own state in response to a received message.
It has several interesting consequences, making message-passing concurrency preferable over shared-state one:

  • Message-passing concurrency is safer: there are no shared resources, so there is no possibility to corrupt data due to concurrent access.

  • Message-passing concurrency is faster: there is no resource synchronization, so there are no bottlenecks, deadlocks, livelocks, or similar locking issues.

  • Message-passing concurrency is easier: once you get used to the new paradigm, not to have to think at how to share and synchronize resources, is a big relief.


The actor concurrency model is a form of message-passing concurrency, based on:

  • Actors: the computational units capable of sending messages and reacting to received ones by executing a given function.

  • Messages: the form of communication used by actors in order to exchange data and carry on some kind of computation based on that data.

  • Mailboxes (or channels): a kind of buffer every actor has for storing received messages which haven't been processed yet.


Every actor can communicate with other actors by obtaining their mailbox (or channel) "address", and then sending a message to it: this is the only way an actor has for changing the state of the system.
Every actor can receive messages and process them by executing a behavior function: such a function can only change the state of the actor itself, or send new messages to other actors (already existent or created on-the-fly).
Communication between actors is completely asynchronous and decoupled: that is, actors do not block waiting for responses to their messages; they just send messages and forget, reacting to incoming messages without any correlation to previously sent messages.
A concurrent system implemented trough the actor concurrency model is considered to be:

  • Parallel: several actors can process several messages in parallel, each one independently from the other.

  • Scalable: actors can be implemented in several ways, as local computational units or distributed ones, so
    they can easily scale out to the number of available processors or computers.

  • Reconfigurable: actors can be dynamically added and removed from the system, and then communicate the new topology through special purpose messages.


Obtaining such a properties through a shared-state implementation is harder and requires a lot of challenges.
The actor model provides instead a well-defined, clearly stated way to easily build highly concurrent systems, at a cost of a paradigm shift.

Next time we will see how to implement an actor-based concurrent application through our favorite OO language: Java!

Saturday, January 31, 2009

Against the viral Commons-Logging

Years ago I wrote a blog post about how to make your application Commons-Logging (JCL) free by using SLF4J.

However, there is still a problem if you're writing a Maven2 based application: even if you're using SLF4J, you will probably end up with a viral JCL jar in your classpath!
That's because JCL is still used by a lot of projects, and Maven places it in your classpath as a transitive dependency.

Fortunately enough, there's still a way to completely, and easily, get rid of it thanks to the jcl-over-slf4j module, and a little Maven trick.

Here's the receipt:


  1. Add the following SLF4J dependencies:

    • slf4j-api

    • logback-classic (or your SLF4J implementation of choice).

    • jcl-over-slf4j




  2. Configure the JCL dependency with scope provided.


So here's how your Maven dependencies should look like:

By doing so, JCL will not be included in your classpath (because Maven considers it to be externally provided), while under the hood will be implemented by SLF4J thanks to the jcl-over-slf4j module.

That's all, folks.
Now you have one, and only one, safe logging library!

Saturday, January 24, 2009

Real Terracotta @ Rome JavaDay 2009

I'm just back from the Rome JavaDay 2009, and here is the presentation I gave: Real Terracotta - Real-world scalability patterns with Terracotta.



I hope you enjoyed it!
I'd be very glad to hear your feedback, so feel free to comment on with any question/thought you may have!

Thursday, January 22, 2009

Follow me on Twitter

Just subscribed to Twitter: http://twitter.com/sbtourist

Feel free to follow me, hoping to tweet interesting stuff at an higher rate than my blogging one ;)

Friday, January 09, 2009

JAX-RS: A proposal for resource URI identification and resolution

In my latest two posts I talked about the problem of clearly defining and resolving the URI of a REST resource in JAX-RS, and then described a possible solution.

I discussed this topic in the Resteasy dev mailing list (here is the thread), and Solomon Duskis suggested to identify resources with a unique logical name rather than with a class name, in order to support multiple REST resources in the same JAX-RS resource, and have less syntax burden.

Building on that suggestion, I've enhanced my proposal and I have to say I'm very happy with it now: as always, feedback is very welcome.

Resource URI identification.

The URI identifying a particular resource is defined by the ResourceUriFor annotation which must be applied to the JAX-RS resource method annotated with the path expression of the URI.
Here it is:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface ResourceUriFor {

public String resource();

public String[] subResources() default {};

public Class locator() default Void.class;
}

The resource argument is the only mandatory one: it defines the logical name of the resource, wich must be unique among all resources.
The subResources argument, optional, defines the logical names of all sub-resources eventually returned by the identified resource, which in this case would act as a locator.
The locator argument, optional, defines the class of the eventual resource locator for the identified resource, which in this case would actually be a sub-resource.

Resource URI resolution.

Resolving a resource URI identified by the above defined annotation is a simple method call:


public interface ResourceResolver {

public URI resolveResourceUriFor(
Class resourceClass,
String resourceName,
String uriBase,
Object... uriParameters);

}


The resourceClass parameter is the class of the JAX-RS resource containing the ResourceUriFor annotation.
The resourceName is the logical name of the resource whose URI has to be resolved.
The uriBase is the base path.
The uriParameters are the objects to use for eventually filling the URI template values.

Resource URI resolution algorithm.

1) Start from resourceClass.
2) Lookup a method annotated with a ResourceUriFor annotation whose logical name is resourceName.
3a) If the ResourceUriFor annotation has no locator, we already have all the elements for resolving the URI.
3b) If the ResourceUriFor annotation has a locator class, go to 4.
4) Go to locator class.
5) Lookup a method annotated with a ResourceUriFor annotation whose subResources contains resourceName of the resource in 2, and go back to 3a.

Monday, January 05, 2009

JAX-RS and HATEOAS : A Proposal

This is a follow-up to my latest post: JAX-RS and HATEOAS, AKA "JAX-RS should provide a way to identify and resolve resource URLs".

I'd like to outline a possible solution, but first, let me recap the problem with a simple example.

The Problem.

JAX-RS let you define web resources out of simple POJOs by properly placing simple, meaningful, annotations.
Let's say we have a Library resource, containing Book resources.

@Path("/")
public class BookResource {

@GET
@Path("/library/book-{id}")
public Response getBook(@PathParam("id") id) {
// ...
}
}


@Path("/")
public class LibraryResource {

@GET
@Path("/library")
public Response getLibrary() {
// ...
List<Book> books = getBooks();
for (Book book : books) {
String id = book.getId();
// Now I have the book id:
// how can I obtain the URL of the resource corresponding to that book?
}
// ...
}
}

So we have two kind of resources, and a relation between the two: from LibraryResource to BookResource.
If you're still wondering why the LibraryResource needs to know the URLs of the BookResources, the answer is Hypermedia As The Engine Of Application State: that is, in a REST application the only way to access the books in the library is to go through the LibraryResource and follow the published book links towards the proper BookResource.
The true question is: how can LibraryResource obtain the BookResource URLs?

The Proposal.

My proposal involves two new annotations and a new utility method.

The ResourceUri annotation must be placed on the web resource method defining the path to use for accessing the resource itself.
It has two arguments: resource (mandatory), defining the class of the identified resource, and locator (optional), eventually defining the resource locator for the resource itself.

The LocatorUri annotation must be placed on the web resource method defining the path for accessing a sub-resource: so, it identifies a sub-resource locator method.
It has two arguments: resources (mandatory), defining the classes of the sub-resources located by the locator method, and locator (optional), eventually defining another locator up in the chain.

Finally, the UriInfo#getResourceUri(Class resourceClass, Object... uriParameters) should resolve the resource URI of the given resource class by inspecting the annotations above.

So, we could rewrite the example above in the following way:

@Path("/")
public class BookResource {

@ResourceUri(resource=BookResource.class)
@GET
@Path("/library/book-{id}")
public Response getBook(@PathParam("id") id) {
// ...
}
}


@Path("/")
public class LibraryResource {

@GET
@Path("/library")
public Response getLibrary(@Context UriInfo uriInfo) {
// ...
List<Book> books = getBooks();
for (Book book : books) {
String id = book.getId();
URI bookUri = uriInfo.getResourceUri(BookResource.class, id);
// ...
}
// ...
}
}


So, with a bunch of annotations and a simple method call, we are now able to clearly say what is the URI that identifies a web resource, and how to resolve it.

What do you think?

Sunday, January 04, 2009

JAX-RS and HATEOAS

This post should have been named something like: "JAX-RS should provide a way to identify and resolve resource URLs".
However, it was too long, so I opted for some buzzy acronyms: let me explain them.

JAX-RS is the official Java API for building Restful Web Services: also known as JSR-311, it went final a few months ago, and is, IMHO, a very good specification, providing an easy and effective way for building REST-oriented web services.
http://www.blogger.com/img/blank.gif

HATEOAS is something more complicated: it would deserve a whole post by its own, but I will try to explain it in a few paragraphs.
First, HATEOAS ishttp://www.blogger.com/img/blank.gif an acronym for: Hypermedia As The Engine Of Application State.
Wow ... you may wonder what does it meahttp://www.blogger.com/img/blank.gifn, so ...
Everyone knows about REST, but too bad, not everyone knows that it's an architectural style, rather than an implementation thing.
More specifically, REST is a way for creating distributed (web) architectures based on some basic principles, and HATEOAS is one of the most important, and often misled/ignored.
HATEOAS could also be named hypermedia-based navigation. It means that a REST application should provide at most one fixed URL: all application URLs, with related resources, should be "dynamically" discovered, and navigated, starting from that fixed URL, thanks to the use of hypermedia links throughout all resources.

That said, the concept of resource URL acquires great relevance: every resource must have its own URL, and that URL must be known by other resources in order to publish it and make the resource accessible.

Now, let's go to my point.
JAX-RS does a very good job at defining resource URLs, but lacks of a way for identifying, as a first class concept, what is the actual URL of a given resource, and hence for resolving it.
Let me give a simple example.
Take a look at the following JAX-RS compliant web resource implementation:

@Path("/resources")
private static class JAXRSResource {

@GET
@Path("/resource")
public String getResource() {
// ...
}

@POST
@Path("/")
public void postResource(String resource) {
// ...
}
}

It defines how to GET and POST the resource, with related paths, but how does it define what really is the URL to use for identifying the resource? And how could another resource refer to it?
For answering the first question, you have to browse all methods, and guess the correct one by looking at the http method annotation (GET), plus its path values.
For answering the second question, you have to hard-code it in the referring resource, or write something like (using JAX-RS APIs) UriBuilder.fromResource(JAXRSResource.class).path(JAXRSResource.class, "getResource").build(): both obscure and error-prone.

So here is my point: again, JAX-RS should provide a way for clearly identifying a resource URL, and easily resolving it.

What do you think?

Saturday, January 03, 2009

Best of 2008

Here is my personal list, just for fun ...

Best of Music
  • The Decemberists - Always the Bridesmaid
  • Shearwater - Rook
  • Okkervil River - The Stand Ins
Best of Movies/TV
  • Zohan (Movie)
  • The Dark Knight (Movie)
  • Dexter (TV)
Best of Tech/Non-Tech Reading
  • Clean Code, Martin (Tech)
  • The Road, McCarthy (Non-Tech)
  • InfoQ.com (Tech)

Now, let the 2009 begin ...

Saturday, December 13, 2008

Presenting at the Rome JavaDay 2009

I'm more than happy to announce that I will present at the third edition of the Rome JavaDay on the 24th of January 2009!
I will host a session entitled Real Terracotta, where I will talk about Terracotta, the most famous open source clustering solution, and how to effectively use it in some real world uses cases.
In particular, these are the use cases I have in mind right now:
  • Data affinity caches.
  • Message processing.
  • Parallel processing.
  • JMX-based cluster management.
Slides will obviously be shared here after the gig.
If you'd like to suggest a particular topic, a particular use case, feel free to drop me a comment: every feedback is, as always, very welcome!

Monday, December 01, 2008

Weekly Digest Ep. 1

I read a number of blogs, and when I see that some of my favorite bloggers don't post anything for a long time, I generally feel disappointed.
So, yesterday I was wondering: how the hell did my readers (if any) feel, given that I generally write one or two posts every two or three months? That should be terrible!!!!

Jokes aside, I decided to write at least a
weekly digest about what happened to me during the last week, what I've been working on, things I've found useful or interesting and similar stuff.

So here it is the first episode, except that it should be a monthly report, this time, given that my latest blog post dates back to months ago!

To make a long story short:
  • I'm working at an highly scalable, highly available, trouble ticketing solution based on Scarlet for a big telco customer.
  • I'm working at an Atom-based application for extracting and publishing Microformats from web pages: I think you will know more very soon.
  • I became a Terracotta Forge committer: more on this very soon!
  • I'm going to become a Spring Extensions lead: again, more on this in the near future!
  • I'm reading Clean Code, which seems to be one of the most interesting and well-written books I've ever read.
  • I renewed the look of my blog ... I hope you like it!
That's all for now.
See you soon ... surely for the next weekly digest episode!

Monday, June 16, 2008

Gridify your Spring application with Grid Gain @ Spring Italian Meeting 2008

Last Saturday I've been at the Spring Italian Meeting in Cagliari, for an enjoyable meet-up with colleagues, friends, and Spring-passionate users.
First of all, thanks to Massimiliano Dessi', the man behind this event ;)
Then, if you lose my presentation about Grid Computing, Grid Gain, and the Spring Framework, here it is:



I really enjoyed presenting it, and I think attendees enjoyed it too: probably because I gave three cool Sourcesense hats to people which made me some questions about the presentation topics ;)
Too bad I can't give you any Sourcesense hat, but I can write down some of the most interesting questions!

Enjoy!

Q: Splitting a task into jobs and sending them to grid nodes involves some overhead due to data transfer: do you have any percentage number that shows you when this overhead is too high compared to what you gain by parallelizing your jobs?

A: I don't believe in magic numbers :)
I'd like to answer your question in a different way: just keep your overhead as little as possible by applying data affinity, that is, by keeping jobs and the data they need together, trying to minimize data transfers.
If you'll not transfer any data, your overhead will be at its minimum.

Q: You talked about data affinity and data grid solutions: what about my database?

A: For really scaling out your application, you must scale your full application stack: hence, your database must scale, too.
I think one of the most effective ways of making you database scale is to partition it, by splitting data into several instances and making every job access a different partition, depending on the data it needs.
Another strategy would be to use a master/replica scenario, where you have a master instance and several read-only replicas, which you map your jobs to for read-intensive operations.

Q: Is there any Grid Gain success story? Do you really use it?

A: Yes, we do :)
We recently developed for the Italian Public Broadcasting Service a custom Content Management System with extended capabilities for life cycle management and rule based publishing of editorial contents.
The publishing infrastructure is made up of a Grid Gain based application managing the publishing cycle of all public web sites, ranging from the main web portal to all related web sites.
It has been implemented for linearly scaling out the publication process from one to hundred sites, by distributing publishing operations on grid nodes, each one capable of publishing contents of one or more sites independently from others: this means that with a number of physical nodes equal to the number of sites to publish, the whole publication process would linearly scale by taking the same time as there were just one site.

Tuesday, June 03, 2008

On the road from Scarlet 1.0 to 1.1

Two months ago, Scarlet 1.0 GA was released: it was a very important milestone in the Scarlet life, completely covering all Jira clustering aspects.
However, there still was one major problem: Jira limited scalability caused by the existent Lucene indexing infrastructure, which was affected mainly by two problems:
  • Synchronous execution of CPU-intensive operations, causing "standard" operations like issue creation to last dozen and dozen seconds on heavy, concurrent, load.
  • Too coarse grained locks guarding CPU-intensive code blocks, causing true scalability bottlenecks.
Today, Scarlet 1.1 Beta 1 has been released, finally bringing a brand new indexing infrastructure, based on the Compass Terracotta-Lucene integration module (thanks guys for the amazing work!) and on the Terracotta distributed Master/Worker implementation, with great performance improvements and true scalability for all Jira users ... cool!
Aside from bug fixes and the upgrade to Jira 3.12.3, this will be the main driving force toward the final 1.1 release: making the new indexing infrastructure robust, fast, and scalable.

And as always, we need your help: so do not hesitate to give it a try and let us know every kind of feedback!

Saturday, March 15, 2008

Scarlet 1.0 RC2 is out!

Short news just to let you know that the Scarlet second release candidate is officially out!

This is your last chance for submitting bugs, suggestions and feedback about Scarlet, prior to its final release, scheduled for the end of this month.

So don't hesitate to contribute to the unique Open Source clustering solution for your preferred enterprise issue tracking software!

Enjoy it!

Monday, February 11, 2008

Scarlet first release candidate is out!

Exciting news about Scarlet are coming!

The new Scarlet 1.0 Release Candidate 1 is officially out, with new features, several enhancements and fixes, and a brand new web site!
Can't wait for it?
Take a look at: http://scarlet.sf.net!

Talking about the technical side of this new release, the most important changes concern the upgrade to Atlassian Jira 3.12, improved APIs for plugin development and a performance boost of about 20%.

However, what most excites me is the new Scarlet infrastructure, based on Sourceforge:

  • The web site, with growing documentation.

  • Forums and mailing lists, for easily getting help, sharing feedback and discussions, and staying in touch.

  • A public Jira space (thanks to Atlassian), for actively contributing to the Scarlet development by tracking bugs and feature requests.

  • A widely accessible download system.


This is to lay the foundation for a true open source community behind Scarlet, which is currently our primary goal ... together with providing you the best Jira clustering solution around, obviously!

Now, it's your turn!

Tuesday, December 11, 2007

See you at Javapolis!

I'm going to leave Rome and catch my flight for Antwerp.
Actual destination : Javapolis!

I will hold a BOF, so don't miss it.

See you there!

Saturday, December 08, 2007

Owner Based Locking explained

If you attended my presentation at the Rome JavaDay about my real world experience in clustering Atlassian Jira, or if you took a look at my slides, you may already know that one of the challenges was the rewriting of the Jira caching system.
The hardest part of this challenge was to define the cache locking strategy.
That was because of two requirements, due to the Jira code and the way it has been clustered:

  • The need to associate more caches under the same lock.

  • The need to execute arbitrary code blocks atomically: that is, again, under the same lock.


So here it comes my idea of the owner based locking.
It's very simple and I'll explain it in a moment: others may find it useful, or elaborate on that for solving their own locking problems, or just provide useful suggestions.

Let's start with the concept of cache group. The cache group is the entry point for your caching system, where you create caches, put things and get back them and alike.

First step : when you create a cache into the group, assign it to an owner.

The owner is a string, and nothing more. It just serves two purposes: it's the name which associates different caches, establishing some kind of caches sub-group, and their lock.

Here it comes the second step : use the owner as a lock for different caches sub-groups.

This is a lock striping technique.
Lock striping techniques prescribe you to distribute your data in several "stripes" and split your big, fat, lock in several locks, assigning each one to a different stripe : this is done for enhancing thread concurrency, given that different threads will be able to concurrently access different parts (stripes) of your data because guarded by different locks.
In our caching system, the stripes are the different caches sub-groups, and the locks are the owners.
A code snippet will help clarifying.
Here is how a value is retrieved from a cache into the cache group:

public Object get(String cacheName, Object key) {
CacheHolder holder = (CacheHolder) this.group.get(cacheName);
String owner = (String) holder.getOwner();
synchronized (owner) {
Map cache = holder.getCache();
return cache.get(key);
}
}

As you can see, the synchronized variable is the owner string: by doing so, caches with the same owner will be protected by the same lock, while caches with different owners will be accessed concurrently, but without compromising the whole thread safety.

Finally : use callbacks for atomically executing code blocks.

This is best explained by first showing the callback interface:

public interface AtomicContext {

public Object execute();
}

And how it's used into the cache group:

public Object executeAtomically(AtomicContext context, String owner) {
synchronized (owner) {
return context.execute();
}
}

As you can see, the execute() method is executed atomically under the given owner lock.
However, here I have to raise a warning flag: if the implementation of the execute() method uses caches belonging to other owners, it may cause deadlocks; so take care and use only caches whose owner is the same as the one provided to the executeAtomically() method!

That's the owner based locking.
You can take the full source code of the cache group used for clustering Atlassian Jira from the Scarlet Jira extension distribution.

Any feedback will be highly appreciated.

Cheers!

Wednesday, December 05, 2007

News about Scarlet

One month has passed since my last post, due to the fact that I've been very busy working at the hottest (well, maybe I'm a bit biased here...) Jira extension around : Scarlet.
Here are some news about it:

  • Me and my colleague and friend Ugo talked about our experience in clustering Jira with Terracotta at the Rome JavaDay: people really appreciated it, and if you weren't there (or if you liked us so much that you want to read them again) you can take a look at the slides (in English language) here.

  • We've just released the Scarlet Beta 2 version! Take a look at the full announcement here.


As always, every kind of contribution will be welcome.
See you!

Tuesday, November 06, 2007

Scarlet is out!

As I said some weeks ago, in the past two months I've been deeply involved in clustering one of the most important Open Source enterprise applications around.

Now, it is time to unveil the amazing work done here in Sourcesense, because the first public beta release of Scarlet is officially out!

Scarlet is a free, open source, clustering extension to Atlassian Jira, providing scalability and high availability to the most famous and widespread issue tracking software.
It is based on Terracotta DSO, so it's a completely transparent / easy-to-setup clustering solution: no new things to learn, no complex configurations to apply, no expensive hardware to buy ... just the same old Jira!

It has been a very challenging work with a lot of interesting technical issues: you'll surely read some articles about them in the (very) near future.

In the meantime, download and learn more about Scarlet here.
Play with it.
We need any kind of feedback : suggestions, feature requests, bug reports and alike.
Do not hesitate.
We need you.

Saturday, November 03, 2007

Introducing the Scala Language

It is both a pure Object Oriented and fully featured Functional language.
It is both a scripting language and a compiled one.
It is a stable, solid, well designed language.
It has been very well received by a lot of people and has thousands of downloads per month.
It runs on the Java Virtual Machine and fully interoperates with the Java environment.
It has been called the "next next Java".
It is the Scala Language.

I've recently started to learn and play with it and I have to say I'm really enjoying its features.
For those with very little Functional Programming background (as I am) it may have a steep learning curve and its language features may seem too vast, but don't let them discourage you!

First start with this excellent tutorial.

Then I suggest you to start learning the following features:
  • All about classes, singleton objects, abstract types and traits.
  • Mixins.
  • Type inference.
  • Infix and postfix operators.
  • XML processing.
These are in my opinion the most important and interesting object oriented capabilities of the Scala language.

Then go with its functional side:
  • All about functions.
  • For comprehension.
  • Case classes (still to learn).
  • Pattern matching (still to learn).
  • Views (still to learn).
  • ... (still to learn).
As you can see, I have still a lot of things to learn, but I think that just its object oriented and most basic functional features make Scala a great language and a great learning/programming experience!

What about some practical use cases?

Right now I see it very well suited for:
  • Creating Domain Specific Languages (DSL) to integrate in Java applications.
  • Producing XML documents starting from data expressed in objects or some kind of DSL.
Stay tuned.
More info and ideas about my experiences with the Scala language will come soon.