score:0
I suggest the best way is to store the mutable variable inside a Akka actor, use message passing in and out of the Akka actor to send and receive this mutable reference. Use immutable data structures.
I have a StorageActor as follows. The variable entityMap gets updated every time something is stored via the StoreEntity. Also it doesn't need to be volatile and still works.
The Akka actor is the place where things can change, messages are passed in and out into the pure functional world.
import akka.actor.Actor
import java.util.UUID
import com.orsa.minutesheet.entity.Entity
case class EntityRef(entity: Option[Entity])
case class FindEntity(uuid: UUID)
case class StoreEntity[T >: Entity](uuid: UUID, entity: Option[T])
class StorageActor extends Actor {
private var entityMap = Map[UUID, Entity]()
private def findEntityByUUID(uuid:UUID): Option[Entity] = entityMap.get(uuid)
def receive = {
case FindEntity(uuid) => sender ! EntityRef( findEntityByUUID(uuid) )
case StoreEntity(uuid, entity) =>
entity match {
case Some(store) => entityMap += uuid -> store.asInstanceOf[Entity]
case None => entityMap -= uuid
}
}
}
score:2
Depending on your use case you might be able to stick with deeply immutable object structures which you partially copy instead of actually mutating them (similar to an "updated" immutable list that shares a suffix with its original list). So-called lenses are a nice way of dealing with such structures, read about them in this SO question or in this blog post.
Sticking with immutable structures of course only works if you don't want changes to be globally observable. An example where immutable structures are most likely not an option are two concurrent clients working on a shared list, where the modifications done by client A must be observable by client B, and vice versa.
score:4
This is a bit of a subjective question, so I won't attempt to answer the 'which is best' part of it. If your chief concern is state in the context of multithreaded concurrency, then one option may be Software Transactional Memory.
There is an Implementation (see the quickstart) of STM as provided by Akka. Depending on your use-case, it might be heavy-weight or overkill, but then again, it might be preferable to a mess of locks. Unlike locks, STM tends to be optimistic, in the same way as database transactions are. As with database transactions, you make changes to shared state explicitly in a transactional context, and the changes you describe will be committed atomically or re-attempted if a conflict is detected. Basically you have to wrap all your state in Refs which can be manipulated only in an 'atomic' block - implemented as a method that takes a closure within which you use manipulate your Ref
s and ScalaSTM ensures that the whole set of operations on your state either succeed or fail - there will be no half-way or inconsistent changes.
This leverages Scala's implicit parameters - all operation to Ref
s require a transaction object as an argument, and this is received by the closure given to atomic
and can be declared implicit, so all the code within atomic
will can be written in a very natural yet safe style.
The catch is, for this to be useful, you do need to use the transactional data-structures provided; so that will mean using TSet
instead of Set
, TMap
instead of Map
. These provide all-or-nothing update semantics when used in the transactional context (within an atomic block). This are very much like clojure's persistent collections. You can also build your own transactional data structures out of Ref
s for use within these atomic
blocks.
If you are not averse to parenthesis, the clojure explanation of refs is really good: http://clojure.org/refs
Source: stackoverflow.com
Related Query
- What is the best way to manage mutable state?
- What is the best way to manage handing off of closeable resources in Scala?
- Scala: what is the best way to append an element to an Array?
- What is the best way to perform OAuth2 authentication using akka-http?
- What is the proper way to remove elements from a scala mutable map using a predicate
- What is the easiest way to deeply clone (copy) a mutable Scala object?
- What is the best way to define custom methods on a DataFrame?
- What is the most elegant way to deal with an external library with internal state using a function programming language?
- What is the best way to format a string in Scala?
- What is the best way to work with akka from nodejs
- What is the best way to implement a request/response protocol using akka and scala?
- What is the best way to check the type of a Scala variable?
- What is the best way to use enrich-my-library in scala?
- What is the best way to deal with compsite keys when using Salat with MongoDB?
- What is the best way to use python code from Scala (or Java)?
- What is the best way to enumerate a list in natural language (Scala)?
- What is the best way to define type safe optional methods in Scala?
- What is the best way to re-establish type coherence after transforming a Tree with Macros
- What is the best way to extend a Java Exception in Scala properly?
- What is the best way to implement google cloud storage?
- What is the best practice way to initialize an actor from the database
- What is the best way to create map in parallel with scala?
- What is the best Scala thread-safe way to write to a BufferedWriter?
- What is the best way to avoid clashing between two typeclass definitions in shapeless
- What is the best way to get the last inserted auto-generated ID using slick?
- What is the preferred way of returning an immutable map from a locally built mutable one?
- What is the best way to get the name of the caller class in an object?
- What is the best way to combine akka-http flow in a scala-stream flow
- What is the best practice for Handling Log message with using functional way
- What is the best way to handle multiple run targets in SBT?
More Query from same tag
- playframework 2.x form redirect with prefill
- How to create a DataSet with 29 columns in Spark
- update json values with json4s for a json path
- Split list based on element value in Scala
- Why is the Scala for-loop (and internals) NumericRange restricted to Int size and how to elaborate the functionality?
- Fetching distinct values on a column using Spark DataFrame
- Limit output with scala on IntelliJ
- Apache Zeppelin 0.6.1: Run Spark 2.0 Twitter Stream App
- Failing spec in Scala/Play during insert into DB(slick)(json request)
- Debugging in IntelliJ Idea 12
- Handle Scala Option idiomatically
- Update Table Hive Using Spark Scala
- How to simplify this code, which uses Option.fold in Scala?
- Scala Null for Double (Min Comparison for Aggregate)
- Spark: Replicate each row but with change in one column value
- Filtering a list based on Optional property in Scala
- issue when using scala filter function in rdd
- Add random elements to keyed RDD from the same RDD
- How to detect untracked future?
- Save XML file to HDFS
- Is Scala case class backed by a Map?
- Is it better to use vals or object when providing instances of a typeclass in Scala
- How to convert Scala Directory (File, Path) to Java java.io.File
- How to create map fields in scala from dataframes?
- How to query the closest item to timestamp in Dynamo DB with Scala
- Spark function avg and BigDecimal's scale issue
- would it work to run scala with vaadin?
- Allocation of Function Literals in Scala
- Annotating constructor parameters in Scala
- (*:update) sbt.ResolveException: unresolved dependency: org.ddahl#jvmr_2.10;2.11.2.1: not found