3

I have the following class in Play for Scala annotated as a Singleton. The objective of the class is to get/close OLAP connections. Question: how to handle the fact that more than one user may access the singleton concurrently? In Java I'd use synchronized, but what about Scala?

@Singleton
class OlapConnectionPool () {

    def getConnection = {
       val dataSource = new SimpleOlapDataSource
       val config = new GenericObjectPool.Config
       //... some connection code

       new PooledOlapDataSource(dataSource, config)
    }

    def close (pods: PooledOlapDataSource) = pods.close

}
ps0604
  • 2,125
  • 16
  • 88
  • 233
  • 4
    Since your singleton is apparently stateless, you don't need to worry about concurrent access ? – C4stor Jun 14 '18 at 08:09
  • Possible duplicate of [How to use synchronized in Scala?](https://stackoverflow.com/questions/34877487/how-to-use-synchronized-in-scala) – Jamie Jun 14 '18 at 18:51
  • @C4stor how do you know it's stateless if i didn't include in the question the commented code? – ps0604 Jun 14 '18 at 23:17
  • Because I wouldn't think you'd omit such an important information by commenting it away ? – C4stor Jun 19 '18 at 14:20

1 Answers1

1

Let us first address a potential issue in your code snippet - each time getConnection is called a new connection pool is created. This represents a resource leak as, most likely, a single connection pool would be sufficient. I would suggest the following refactor:

@Singleton
class OlapConnectionPool () {
  private val ds = {
    val dataSource = new SimpleOlapDataSource
    val config = new GenericObjectPool.Config
    //... some connection code 
    new PooledOlapDataSource(dataSource, config)
  }

  def getConnection() = ds.getConnection()
  def close() = ds.close()
}

Here ds is initialised only once upon singleton construction, so there is a single connection pool for the life-span duration of the singleton.

Singletons are thread-safe as longs as they are not publicly exposing shared state, for example, via public var members, and all the dependencies of the singleton are also thread-safe. Hence we need to determine if the dependency PooledOlapDataSource is thread-safe. I am guessing PooledOlapDataSource is from pivot4j, so inspecting PooledOlapDataSource source code we can see it depends on PoolableObjectFactory, which according to docs is thread-safe:

PoolableObjectFactory must be thread-safe.

Furthermore if we inspect dependencies of PoolableObjectFactory.getConnection we arrive at borrowObject call where we see bunch of synchronized sprinkled in. Therefore it is probably safe to conclude your singleton is thread-safe.

Also, have a look at this interesting answer where the author recommends to:

In general, it is probably best to not use @Singleton unless you have a fair understanding of immutability and thread-safety.

Mario Galic
  • 41,266
  • 6
  • 39
  • 76