Circumflex Blog

web framework, object-relational mapper and other cool things for Scala

Posts tagged circumflex

0 notes &

2.0 is coming

My dear friends, I am happy to announce the first successful build of an entire Circumflex 2.0 suite! There are a lot of changes in 2.0, some of which will require you to revisit your code. We thank you for your patience and we are sorry for all inconveniences: it is probably the cost of innovation and establishing maturity. I’m sure you won’t run into problems with these changes, though, I want to assure you that the API became stable enough and that no more big reorganizations surprises await your application code in the near future.

You can start using Circumflex 2.0 right now, it’s in a separate branch at GitHub. The release, however, will be made only when the proper source documentation level is achieved, as well as when all subtle issues are resolved. Until then you are free to share your ideas and opinions with us!

0 notes &

Circumflex ORM 2.0 Reorganization

Well, it’s been quite an effort to develop an SQL-like DSL for data access for Scala. The model we’ve came up to is already good and beautiful, but I’ve summarized all the issues (custom PK types, cyclic dependency problems between Record and Relation, evaluation of uuids on each record instantiation, etc.) and I think we cannot maintain this model as it is anymore.

The main issue is of course the Record-Relation cyclic dependency (the so-called chicken-or-the-egg issue of Circumflex ORM 1.1). I don’t think it’s been raised by the community, so I’ll explain a bit. In short, we have two abstractions, Relation and Record. Relations are meant to be singletons, which produce record instances. In turn, records need to be aware of their relation. That’s fine. Now in order to build predicates in a DSL fashion, we need to reference fields declared in records from relation-level scope:

val co = Country as "co"   // give our table an SQL alias
co.name EQ "United Kingdom"  // construct a predicate

In the example above name field is declared inside record, not inside relation. So how does this compile and work? It’s because we use some magic here. Internally, every relation instantiates a sample record inside during it’s initialization. Relation then can be implicitly converted into Record to point to it’s fields (there are actually lots of things we do about this recordSample, but they do not matter for now). Now the issue. Because initialization code of relation instantiates a record, you cannot reference this relation inside record’s initialization block. Try it:

class Country extends Record[Country] {
  println(Country.toString)
}

object Country extends Table[Country]

You’ll get NullPointerException as soon as you attempt to access either the Country singleton or instantiate the Country record.

Why would you use the relation object inside record? This question is out of my scope. The only thing that matters is the fact that you can’t do that. It’s a limitation. And we should get rid of it at any cost.

Fortunately, I’ve came up with a solution, but the cost is significant. It will require not only complete library rewriting, but will also eliminate all backward compatibility of users code. The data definition code will look like that:

class Country extends Record[Country](Country) { ... }

object Country extends Country with Table[Long, Country]

You see, the Country singleton now extends Country itself, thus it has all it’s fields (this eliminates the need for implicit conversions when constructing predicates). This approach also eliminates that notorious cyclic dependency problem.

But apart from the hard work on complete rewriting and backward compatibility problems, there are some open questions on this solution.

  • Since relation extends record now, it will inherit ambiguous methods applicable only to record instances (such as insert, update or delete) — what should we do with them? Throw exceptions?

  • Just like with recordSample, assignment to the fields of the relation does not make any sense:

    Country.name := "New Zealand"    // wut?
    
  • It is even possible to mistakenly add a relation into the collection of records and include it into mass processing which would make absolutely no sense (and possibly introduce runtime errors):

    var countries = Country.all()
    countries ++= List(Country)
    countries.foreach { c =>
      c.code := c.code().toLowerCase    // no sense for relation
      c.update    // unacceptable for relation
    }
    

That’s kinda it, thanks for your attention. I would appreciate all your opinions and ideas.

0 notes &

Context API

Hi, friends and colleagues!

As I’ve mentioned before in Circumflex 2.0 we are planning to introduce Context API.

So, what is context? Essentially it is a ThreadLocal storage which allows you to share objects within a logical scope. Such logical scope could be anything: database transaction, HTTP request, user session within GUI form, etc.

Context is a rather common concept in programming. It lets you avoid passing too much parameters between collaborating classes (remember plain-old Servlet API where you had to pass explicitly HttpServletRequest and HttpServletResponse between controllers).

Let’s take a lot at some sample code:

class MyServlet extends HttpServlet {
  override def doGet(req: HttpServletRequest, res: HttpServletResponse) = {
    new MyController1(req, res)
    val c = new MyController2
    c.doWork(req, res)
    c.doMoreWork(req, res)
  }
}

class MyController1(req: HttpServletRequest, res: HttpServletResponse) { ... }

class MyController2 {
  def doWork(req: HttpServletRequest, res: HttpServletResponse) = { ... }
  def doMoreWork(req: HttpServletRequest, res: HttpServletResponse) = { ... }
}

This snippet shows a servlet which passes request and response objects into two controllers. You see, controllers declare that they depend on HttpServletRequest and HttpServletResponse using their constructors and method parameters. If you have thousands of controllers which are executed inside web application and must be aware of request and response, these boilerplates become really annoying. The same could be done using contexts:

class MyServlet extends HttpServlet {
  override def doGet(req: HttpServletRequest, res: HttpServletResponse) = {
    ctx("request") = req
    ctx("response") = res
    new MyController1()
    val c = new MyController2
    c.doWork()
    c.doMoreWork()
    Context.destroy
  }
}

class MyController1 { ... }

class MyController2 {
  def doWork = { ... }
  def doMoreWork = { ... }
} 

You see, the code of servlet becomes a little more complex: context initialization and context destruction are required to define a logical scope, but controllers become much simpler. Since it is clear that controllers are only executed inside context scope, they can use context variables request and response inside their code.

There is, however, one important downside of this approach: classes that rely on context (i.e. expect a context to contain necessary parameters) are harder to debug since they do not “show” their dependencies to the world via public constructors or method parameters. The documentation of such classes should always reflect their expectations about the contents of context.

Circumflex Context API is as simple as one-two-three sequence.

  1. The boundaries of context scope are set using Context.init and Context.destroy. The latter step is extremely mandatory. If threads are reused using some kind of thread pool, finalization ensures that context does not contain orphaned data from previous owners. Circumflex Web Framework, for example, performs context initialization and finalization using CircumflexFilter, it also injects HttpRequest and HttpResponse into context. You can also add listeners for context initialization and finalization events:

    Context.addInitListener(c => println("Context initialized."))
    Context.addDestroyListener(c => println("Context destroyed."))
    

    Circumflex ORM 2.0, for example, uses this approach to ensure that all data access within context scope is performed within a single database transaction without having to redefine the scope of the context.

    The last thing to know about context lifecycle is that it is initialized implicitly on first access if it hasn’t been initialized before.

  2. You can work with current context from any code that is ran inside it’s scope. You simply call Context.get (or a shortcut, the ctxmethod of package object ru.circumflex.core). Context extends mutable Scala map, so it should be already familiar to you:

    // set context variable
    ctx("key") = value
    // access context variable
    ctx.get("key") match {
      case Some(v: MyExpectedType) => ...
      case _ => ...
    }
    

    You can also rewrite the above snippet using nice and handy DSL:

    // set context variable
    'key := value
    // access context variable
    'key.get match {
      case Some(v: MyExpectedType) => ...
      case _ => ...
    }
    
  3. You can configure Circumflex to work with your own context implementation:

    package com.myapp
    
    class MyContext extends Context {
      def myUsefulContextScopedMethod = {...}
    }
    
    object MyContext {
      def get: MyContext = Context.get.asInstanceOf[MyContext]
    }
    

    Then simply override cx.context configuration parameter:

    cx.context=com.myapp.MyContext
    

    And access your own context from your code:

    MyContext.get.myUsefulContextScopedMethod
    

To summarize, there are a lot of things you can do with context. For example, we pass context object as a root data object to Freemarker templates so that you can pass your variables from request routers to views.

Now enough reading. Go and create some software masterpiece with Circumflex. Good luck :)

0 notes &

Upcoming Messages API

Hey, guyz!

In upcoming release of Circumflex 2.0 we introduce a handful of tiny classes under a loud name, Messages API. They let you internationalize your application with minimal effort, have sensible defaults and offer some robust, from out point of view, techniques which will let you save some typing.

So, first of all, messages are resolved by key. The default source is good ol’ Java ResourceBundle with default base name Messages. This default approach lets you easily add l10n capabilities to your app, just assign your messages some keys and create as many localized Messages.properties files as you want (see Java Internationalization Trail for more information).

You retrieve message by key by accessing the msg method of package ru.circumflex.core. It acts like singleton (you can call it from anywhere) except that it takes locale from Context (we’ll talk about contexts later).

Now secondly, your deployment might have some specific requirements for resolving your messages. DelegatingMessageResolver comes in handy if you have different sources, which are prioritized (i.e. each resolver in a list is asked for a message and first successfully resolved message is returned).

You can also implement your own MessageResolver and specify cx.messages configuration parameter to override the default one (so that the msg method could return your implementation instead of ours).

Well, what’s next? Ah, yeah. We are way more loyal to your property files that standard Java ResourceBundles. Messages are resolved by a range of keys, from more specific to the most general. For example, if you are looking for a message with the key “com.myapp.model.Account.name.empty”, the message will actually be resolved using following list of keys (until first success):

com.myapp.model.Account.name.empty
myapp.model.Account.name.empty
model.Account.name.empty
Account.name.empty
name.empty
empty

This gives you brilliant opportunity at keeping you property files shorter, for example, if all your messages for empty fields sound the same (like “The field is required, really.”), then you may simply specify one message with key “empty”. All validation messages from Circumflex ORM with error key “empty” will then be resolved into this message.

And the last neat thing, you may format your messages on-the-fly:

msg.fmt("hola", "name" -> "Peter")

If you have following message in your Messages.properties:

hola=Hello, {name}!

Then the expression above will yield, as you’ve already guessed, “Hello, Peter!”. Also standard MessageFormat style (you know, with {0}’s and vararg arguments) is available via format method.

So, that’s it. You can see what we’ve implemented so far. Any comments and additions would be highly appreciated. Thanks.

0 notes &

Working on 2.0

Dear friends!

We are currently in a middle of major reorganization of Circumflex API, which will soon be known to the world as Circumflex 2.0. This reorganization implies breaking Circumflex Core module into two:

  • circumflex-core, which will only contain Context API, Configuration API, Messages API and some utilities;
  • circumflex-web will contain full-blown Web Application Framework with main ideas from Circumflex 1.x.

As a result, Circumflex ORM and all other components will no longer depend on Servlet API.

New set of functionality is coming out, too. Circumflex 2.0 will feature more robust API for accessing request and response, as well as file uploading, more flexible transaction demarcation patterns and some SQL dialects in ORM. We will also get our hands dirty on documenting our stuff, so you won’t need (hopefully) to look through our sources to understand, how things work.

Circumflex 2.0 will also feature support of Scalate templates. Chirino’s branch already contains the module and shows how to use their view technologies on ciridiri and cx-site. circumflex-scalate module will be included in 2.0 release.

We do our best to keep backward compatibility with Circumflex 1.x. However, some architectural improvements will require you to revisit your code.

You can monitor our progress at branch 2.0.

Thank you for using Circumflex, guys! Have fun!