Jack
Jack

Reputation: 16718

What is a good strategy for keeping global application state in Scala?

As a simplest example, say I'm starting my application in a certain mode (e.g. test), then I want to be able to check in other parts of the application what mode I'm running in. This should be extremely simple, but I'm looking for the right Scala replacement for global variables. Please give me a bit more than : "Scala objects are like global variables"

The ideal solution is that at start-up, the application will create an object, and at creation time, that object's 'mode' is set. After that, other parts of the application will just be able to read the state of 'mode'. How can I do this without passing a reference to an object all over the application?

My real scenario actually includes things such as selecting the database name, or singleton database object at start-up, and not allowing anything else to change that object afterwards. The one problem is that I'm trying to achieve this without passing around that reference to the database.

UPDATE:

Here is a simple example of what I would like to do, and my current solution:

object DB{
  class PDB extends ProductionDB
  class TDB extends TestComplianceDB
  lazy val pdb = new PDB
  lazy val tdb = new TDB
  def db = tdb //(or pdb) How can I set this once at initialisation?
}

So, I've created different database configurations as traits. Depending on whether I'm running in Test or Production mode, I would like to use the correct configuration where configurations look something like:

trait TestDB extends DBConfig {
  val m = new Model("H2", new DAL(H2Driver),
    Database.forURL("jdbc:h2:mem:testdb", driver = "org.h2.Driver"))

  // This is an in-memory database, so it will not yet exist.
  dblogger.info("Using TestDB")
  m.createDB
}

So now, whenever I use the database, I could use it like this:

val m = DB.db.m
m.getEmployees(departmentId)

My question really is, is this style bad, good or ok (using a singleton to hold a handle to the database). I'm using Slick, and I think this relates to having just one instance of Slick running. Could this lead to scalability issues.

Is there a better way to solve the problem?

Upvotes: 2

Views: 578

Answers (1)

EECOLOR
EECOLOR

Reputation: 11244

You can use the typesafe config library, this is also used in projects like Play and Akka. Both the Play and Akka documentation explain basic parts of it's usage. From the Play documentation (Additional configuration)

Specifying alternative configuration file

The default is to load the application.conf file from the classpath. You can specify an alternative configuration file if needed:

Using -Dconfig.resource

-Dconfig.resource=prod.conf

Using -Dconfig.file

-Dconfig.file=/opt/conf/prod.conf

Using -Dconfig.url

-Dconfig.url=http://conf.mycompany.com/conf/prod.conf

Note that you can always reference the original configuration file in a new prod.conf file using the include directive, such as:

include "application.conf"

key.to.override=blah

Upvotes: 4

Related Questions