I was looking at some open source scala project. and I saw that some are doing something like :
abstract class Foo{
def create(implicit ex: ExecutionContextExecutor): Seq[ResultSet] = {
Await.result(createAsync(), timeout)
}
def createAsync()(implicit ex: ExecutionContextExecutor): Future[Seq[ResultSet]] = //implementation
... more like those
}
is there any advantage/disadvantage for calling each method with
(implicit ex: ExecutionContextExecutor) parameter rather than passing the ExecutionContextExecutor in the class constructor:
abstract class Foo(implicit ex: ExecutionContextExecutor){
def create(timeout: FiniteDuration): Seq[ResultSet] = {
Await.result(createAsync(), timeout)
}
def createAsync(): Future[Seq[ResultSet]] = //implementation
... more like those
}
is there preferred option ?
The former approach gives you more flexibility as to where the execution of createAsync will be scheduled, since each time you can make a decision as to which ExecutionContext you want to pass in. Question is, do you need that flexibility? I find that most of the times a single ExecutionContext is sufficient, but it is really a matter of case by case analysis.
In general, the first snippet is horrible IMO. Exposing a synchronous wrapper which blocks around an asynchronous operation is usually a sign of a code smell, and code like that doesn't scale well.
Related
I'm in a situation where I need to set a certain field in a singleton object so it can be used later.
def register(importantField: String): Unit = {
Factory.setField(importantField)
}
where Factory is:
object Factory {
var field: Option[String] = None
def setField(importantField: String): Unit = {
field = Option(importantField)
}
def functionThatWillBeCalledLater: Unit = {
// do something with member "field"
}
}
but I really want to avoid using var. Is there some kind of idiomatic way to do this?
Don't do this. Global factories, besides being racy and breaking referential transparency, are also a nightmare for unit testing. You should really think about designing your code in a way, where you can keep all the "important fields" where you need them.
The trick is that instead of something like
class Foo {
def doFoo() = Factory.bar
}
Factory.register(param)
new Foo().doFoo()
You would have to write
class Foo {
def doFoo(factory: Factory) = factory.bar
}
new Foo().doFoo(new Factory(param)
Or maybe
class Foo(factory: Factory) {
def doFoo() = factory.bar
}
new Foo(new Factory(param)).doFoo
It may seem a bit tedious compared, to just throwing all the stuff into a global state object, and accessing it from everywhere ... but that's only as long as all of the uses of that function everywhere always use the same value of the parameter (in which case, it is better off just being a constant in the first place) or (perhaps, more importantly) until you start thinking about writing unit tests to test places that use your Factory. You cannot mock an object ... so, what will you do?
Singleton objects have to be thread safe - since the object is static, there's no guarantee that only one thread will access it, so your call not to use a var is totally reasonable. All vals are final and guaranteed to be thread safe, but we can't say the same about vars (and, well, if we're talking about idiomatic, mutable state is generally frowned upon).
You could implement your own getter and setter (using proper synchronization) for a private var, or use a scala.concurrent.Promise for this purpose - a Promise can only be completed once, and is guaranteed to be thread safe.
import scala.concurrent.Promise
object Factory {
private val _field: Promise[String] = Promise()
// the notation below allows you to set it via `Factory.field = "a"`
def field_=(value: String): Boolean = _field.trySuccess(value)
def field: Option[String] = _field.future.value.flatMap(_.toOption)
}
That said, the most idiomatic Scala way to approach factories with variable baseline conditions would be to create one with all the variables set to the values you need. An object is essentially just a val, so instead of an actual singleton object you could instantiate the Factory with all the parameters you need once they're available - and then just use that everywhere.
I'm new in scala programming. I'm puzzled now for how to declare a biz method in a asynchronous and functional way, that the method implementation should include many log message. As a bad practice, I write the code like this :
// trait
trait StoreService {
def create[Config]: Kleisli[Future, Config, Store]
}
// and the interpreter
trait StoreServiceInterpreter extends StoreService {
def create[Config]: Kleisli[Future, Config, Store] = Kleisli {cfg =>
// some implementation ...
log.info("bla bla bla ...")
// some implementation ...
// return a store
Store(...)
}
}
It's bad, cause the implementation is with side-effect, log something int the place. So, I change the method declaration like this:
// trait
trait StoreService {
def create[Config]: Kleisli[Future, Config, Writer[Vector[String], Store]]
}
// and the interpreter
trait StoreServiceInterpreter extends StoreService {
def create[Config]: Kleisli[Future, Config, Writer[Vector[String], Store]] = Kleisli {cfg =>
// some implementation ...
// log.info("bla bla bla ...")
// some implementation ...
// return a store
Writer(Vector("bla bla bla...", Store(...))
}
}
Using the Writer, the side-effect is eliminated, but the code is not clear:
Why a writer returned? Writer[Vector[String], Store] has more noises than Store, has any way to avoid the boilerplate code and remain the no-side-effect?
Write log is not ad-hoc! I should build a vector of String to hold the message, using :+ or ++ operation to add log. I think it's not ad-hoc logging, just like write log.info(...) anywhere.
Most of Scala developers I know tend to consider logging as "non-side-effect", for convenience. However, if you really want to track them, you might want to take a look on "free monad" concept. Further information:
general description, example with logging.
Mine rough explanation is "let's model our program as some AST and interpret it". So, in AST you define a concept of "logging" but not implementation, that comes later, in interpretation. This approach allows you to keep an eye on logging and change the action (from write to /dev/null to async post to external service) without affecting the "business" part of your code.
Very many times, I'll want to "replace" a single method of a given object.
foo: Foo
foo.bar(i) // original
foo.baz(s) // replace this implementation
I'll wind up creating a pass-through wrapper class.
class FooWrapper(foo: Foo) extends Foo {
def bar(i: Int) = foo.bar(i)
def baz(s: String) = foo.baz(s)
}
And then
foo: Foo
val foo2 = new FooWrapper(foo) { def baz(s: String) = ... }
foo2.bar(i)
foo2.baz(s)
This works with traits and classes, and works without modifying the source code of the type.
I use this quite a bit, particularly when adapting libraries or other bits of code.
This can get tedious with lots of methods. The other day, I wanted to replace the shutdown method on an ExecutorService instance, and I had to do this for a dozen methods.
Is this a common idiom, or is this normally done another way? I suspect this could be done nicely with a macro, though I haven't found any existing ones that do this.
You can achieve that with AOP (Aspect-oriented programming)
There're many libraries to do so, try this one -
https://github.com/adamw/scala-macro-aop
Note that this library is in POC stage for now so you might look for something more mature. I've put it here because I think it shows the concept very clearly.
For your example you'll have to do something like
class FooWrapper(#delegate wrapped: Foo) extends Foo {
def baz(i: Int) = ???
}
The question is self explanatory, but please allow me to provide an example:
I have the following:
class Foo {
def doAndPrint {
val result = doSomething()
val msg = message(result)
println(msg)
}
private def message(result: Result): String = {
"message formatted with %s".format(result)
}
}
In this context, the question is: Should def message(result: Result) live in object Foo?
The argument in favor is making explicit that def message(result: Result) does not depends on any state within class Foo.
The argument against is that the motivation of companion objects was to provide a place to put java public static methods.
The answer to this false dichotomy is neither. It should be a local method to doAndPrint.
class Foo {
def doAndPrint {
val result = doSomething()
def message(result: Result): String = s"message formatted with $result"
val msg = message(result)
println(msg)
}
}
In fact,
class Foo {
def doAndPrint {
val result = doSomething()
def message = s"message formatted with $result"
println(message)
}
}
Notice that it really depends on local state.
Edit: OK, as a nod to "self-explanatory," I would add, use the smallest scope that makes sense, and the example points out an asymmetry in the private relations between companions. Which begs for many puns which I haven't time to supply.
Answering more directly, from my observations, the companion module does not normally serve as a repository for FooUtil-style functions, though it does serve as a repository for implicit conversions, which have an arguably similar flavor, albeit public. Consider what winds up in the objects of collection types.
Consider a separation of concerns:
class Foo(f: String => Unit) {
def doSomethingAndDoSomethingWithIt {
val result = doSomething()
def message = s"message formatted with $result"
f(message)
}
}
You should put the methods where they belong. If you need to break things up for testing purposes, readability or even maintainability then you need to break them up. Even though Scala is influenced by FP concepts, FP patterns, and an FP mindset, it is still also an OO language.
Private helper methods are just that, helper methods to make your code easier to work with. If your class needs them, then there is no reason to spread out that logic in another class... just 'cause. Put them in the same place (and add in some means to access those methods for unit testing purposes like package visibility.)
Please excuse my poor understanding of Scala. I'm just a Java developer that wants to get something working in the Play Framework. I even attempted to implement a trait using Java code, but I got even more obscure errors. I have the following Scala code:
package models
import scala.concurrent.Future
class SettableFuture[T](name: String) extends Future[T] {
var assignedValue: T
def set(newValue: T) =
assignedValue = newValue
//override abstract methods in Future[T]
def ready(atMost: scala.concurrent.duration.Duration)(implicit permit: scala.concurrent.CanAwait): models.SettableFuture[T] =
this
def result(atMost: scala.concurrent.duration.Duration)(implicit permit: scala.concurrent.CanAwait): T =
assignedValue
def isCompleted: Boolean =
false
def onComplete[U](func: scala.util.Try[T] => U)(implicit executor: scala.concurrent.ExecutionContext): Unit =
null
def value: Option[scala.util.Try[T]] =
null
}
And here's my error:
overriding method ready in trait Awaitable of type (atMost: scala.concurrent.duration.Duration)(implicit permit: scala.concurrent.CanAwait)SettableFuture.this.type; method ready has incompatible type
Ignore the return values of the methods for now, they're nonsensical because I'm just trying to fix all the compile errors.
I simply copied the method stubs from the compile time exception when extending a trait without overriding its abstract methods and pasted them into my source file. I don't understand why I'm still getting errors. I took a look at the signature for ready() in Awaitable and it looks like the return type should in fact be the class.
EDIT: the reason why I want to implement this is because in the Promise/Future Scala API, I can only find things that let me asynchronously execute long-running, blocking tasks. What I'm after is something that lets execution of a request be suspended until something of interest sets a value in the SettableFuture instance, which completes a Promise to send a response. In this way, it's somewhat like a continuation. Anyway, here is the working code that I ended up with:
package models
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
import scala.concurrent.CanAwait
import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.concurrent.duration.Duration
import scala.util.Try
class SettableFuture[T]() extends Future[T] {
private final val ValueNotSet = 0
private final val ValueBeingSet = 1
private final val ValueSet = 2
private val valueStatus: AtomicInteger = new AtomicInteger(ValueNotSet)
private val onCompleteWaitHandle: CountDownLatch = new CountDownLatch(1)
private var onComplete: Try[T] => _ = _
private var assignedValue: T = _
/** Set a value and complete this Future.
*
* Returns false if the value has already been set by a past call to this method.
* Otherwise, marks this Future as complete, executes the function passed to
* onComplete, and finally returns true.
*/
def set(newValue: T): Boolean = {
//set value and trigger onComplete only once
if (valueStatus.compareAndSet(ValueNotSet, ValueBeingSet)) {
assignedValue = newValue
valueStatus.set(ValueSet)
onCompleteWaitHandle.countDown()
if (onComplete != null)
onComplete(Try(assignedValue))
true
}
false
}
//override abstract methods in the Future[T] trait
def ready(atMost: Duration)(implicit permit: CanAwait): this.type = {
onCompleteWaitHandle.await(atMost.length, atMost.unit)
this
}
def result(atMost: Duration)(implicit permit: CanAwait): T = {
ready(atMost)
assignedValue
}
def isCompleted: Boolean = (valueStatus.get() == ValueSet)
def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit =
onComplete = func
def value: Option[Try[T]] = {
if (!isCompleted)
None
Some(Try(assignedValue))
}
}
In terms of the specific error you are getting, the ready method you are overriding has a return type of Awaitable.this.type - ie. the specific type of this instance of Awaitable (the super type of Future, so that in Future, this method is seen to have return type Future.this.type). For your SettableFuture class, this means the return type for the ready method needs to be models.SettableFuture.this.type.
Other minor problems you can expect to hit: the onComplete method's implementation should be {}, not null, as the latter is a return of type Null.type, not Unit, and the var assignedValue needs to be initialised in a non-abstract class, which can be done by adding = _ to the line defining the variable (although you really want to make it at least protected, and provide an accessor which will check if it has been set - maybe by changing the variable to an Option[T] initialised to None, or else maintaining a Boolean flag that can be checked in the accessor, and which is set to true by the set method).
In terms of what it looks like you are trying to achieve, however, you might just want to check out scala.concurrent.Promise, which represents a "promise of a future result". It has a method future that returns a Future, and various complete, completeWith, and similar methods that can be used to set the Promise's value, which in turn will cause the associated Future to become ready/completed.
The SettableFuture class unnecessarily mixes the two concerns that the Future and Promise traits were designed to separate:
asynchronous provision of a value (Promise), and
waiting for and reacting to that provision (Future)
Rather than thinking of a Future as an asynchronous, long-running, blocking computation, it may help to think of it simply as a value that may be provided at some future time. You can react to provision of that value in a number of ways, including registering a callback or mapping it to some other value. For example, in Play one will often suspend processing of a request with a pattern like this (in Scala):
def handleRequest = Action {
Async {
gimmeAFuture().map(value => Ok(value))
}
}
def gimmeAFuture(): Future[JsValue] = // ...
The gimmeAFuture method returns a Future, but the request handling code doesn't care about how the value is computed. It could be
computed immediately with Future.successful,
computed asynchronously with Future.apply, or
supplied by the completion of a Promise
As an example of the latter, the gimmeAFuture method might be implemented as follows:
def gimmeAFuture: Future[JsValue] = {
val p = Promise.apply[JsValue]()
// asynchronously complete the promise 30 seconds from now
scheduler.scheduleOnce(30.seconds)(p.complete(Success(someJsObject)))
// return the future immediately
p.future
}
Of course, you could implement that method however you want. The key is that something will need to hold on to that Promise object and complete it with a value in order to resume handling of the request. The request handler itself does not get a reference to the Promise object, since it only cares about the value that will be computed (i.e., the Promise's Future).
I revisited this question after finding this link and I realized why there was so much confusion.
I was planning on using the SettableFuture class because I couldn't find anything like it that already existed in the Play Java API. I wanted something equivalent to a TaskCompletionSource in .NET, and Aaron's answer made it really clear that Scala had exactly what I needed. Unfortunately, I couldn't find the equivalent in Play's Java API.
That link cleared up exactly why I was having so much difficulty over something that should have been so simple. Thanks all for answering my question!