Events in Scala - scala

I have a CategoryRepository class which implements several methods such that saves a category to database.
I also have an object Product that contains a list of categories.
What I want to do is to trigger an event that the Product object will listen to, and will update the product itself with the new data of its category.
In C# I know I can use delegates but I don't know if I can do something like this in Scala.
I don't want the CategoryRepository class to know the class Product so I won't call some method in Product that will update it through CategoryRepository.
My CategoryRepository class:
trait CategoryRepositoryComponentImpl extends CategoryRepositoryComponent {
val categoryRepository = new categoryRepositoryImpl
class CategoryRepositoryImpl extends CategoryRepository {
val dbRepository = CategoryDbRepository
def updateAttribute(id:String, request:UpdateCategoryItem): String = {
val cat = dbRepository.get(id)
cat.update(request)
dbRepository.save(cat)
}
}
}
The product repository looks the same as this category's repository.
Now I want to add a line after dbRepository.save(cat) that will trigger an event that will call the updateProduct() function within ProductRepository.
Please give an implementation example.
Thanks.

a (not so) basic implementation for an update channel based on events.
I took care to only generalize to the bare bone, as to give a hint to future evolution and code reuse.
Base infrastructure
We introduce an updates channel
//Listens for updates to A's and notifies interested listeners
class UpdateChannel[A] {
//simplified register
var listenMap: Map[A, Listening[A]] = Map()
//update call
def apply(a: A): Unit = listenMap.get(a).foreach(_.event(a))
//update call
def registerFor(a: value, listen: Listening[A]) = listenMap += (a, listen)
}
and a generic listener interested in corrisponding updates
//Listens to changes for type A
trait Listening[A] {
def event(upd: A): Unit
}
Application
Now we adapt the Repo Component to inject the channel
trait CategoryRepositoryComponentImpl extends CategoryRepositoryComponent {
val categoryRepository = new categoryRepositoryImpl
/************** NEW CODE HERE **************
* define a channel to send category updates
*******************************************/
def updateChannel: UpdateChannel[Category]
class CategoryRepositoryImpl extends CategoryRepository {
val dbRepository = CategoryDbRepository
def updateAttribute(id:String, request:UpdateCategoryItem): String = {
val cat = dbRepository.get(id)
cat.update(request)
dbRepository.save(cat)
//send the update to the channel
updateChannel(cat) //***************** << AND HERE
}
}
}
We also need to enable the product to event listening
//product must be listening to category updates
class Product(val category: Category) extends Listening[Category] {
def event(cat: Category) = ??? //strut your stuff here
...business stuff here too
}
Finally, here we put the ingredients together
//put the pieces together
def wireup() = {
//the channel
val catChan: UpdateChannel[Category] = new UpdateChannel[Category]
//the Repository component wired to the channel
val catRep = new CategoryRepositoryComponentImpl {
val updateChannel = catChan
}
//a nice cat
val myCat: Category = ???
//a nice prod with her nice cat
val p: Product = new Product(myCat)
//prod wants to know what happens to her cat
catChan.registerFor(myCat, p)
}
Remarks
we can make the Product independent of the whole framework by using refinement types
val product = new Product(myCat) with Listening[Category] {
def event(cat: Category) = ??? //strut your stuff here
}
a different solution would be to avoiding all the wirings and simply register a list of update closures in the RepositoryComponent
trait CategoryRepositoryComponentImpl extends CategoryRepositoryComponent {
val categoryRepository = new categoryRepositoryImpl
//public listeners, they should be encapsulated
var categoryUpdates: Seq[Category => Unit]
[...]
def updateAttribute(id:String, request:UpdateCategoryItem): String = {
val cat = dbRepository.get(id)
cat.update(request)
dbRepository.save(cat)
//send the update to the channel
categoryUpdates.foreach(_.apply(cat))
}
}
}
and the product needs only to add his own update function
catRep.categoryUpdates +:= (cat) => p.event(cat)

I think this would be more or less how it's done in C# with events and delegates.
When you define Event like this you'd have to use tuples (Event[(Any,EventArgs)] for instance) if you want to pass more than one parameter to the event listeners.
class Event[Arg] {
type L = Arg => Unit
private val listeners = scala.collection.mutable.ListBuffer.empty[L]
def +=(listener: L) {
listeners.append(listener)
}
def apply(arg: Arg) {
listeners.foreach(_(arg))
}
}
class CategoryRepository {
val event = new Event[String]
def fireEvent(data: String) {
event(data)
}
}
object Product {
def update(data: String) {
println(s"updating: $data")
}
}
object Main extends App {
val repo = new CategoryRepository()
repo.event += Product.update
repo.fireEvent("new data")
}

Related

Is there any way to rewrite the below code using Scala value class or other concept?

I need to write two functions to get the output format and the output index for file conversion. As part of this, I wrote a TransformSettings class for these methods and set the default value. And in the transformer class, I created a new object of TransformSettings class to get the default values for each job run. Also, I have another class called ParquetTransformer that extends Transformer where I want to change these default values. So I implemented like below.
class TransformSettings{
def getOuputFormat: String = {
"orc"
}
def getOuputIndex(table: AWSGlueDDL.Table): Option[String] = {
table.StorageDescriptor.SerdeInfo.Parameters.get("orc.column.index.access")
}
}
class Transformer{
def getTransformSettings: TransformSettings = {
new TransformSettings
}
def posttransform(table: AWSGlueDDL.Table):Dateframe ={
val indexAccess = getTransformSettings.getOuputIndex(table: AWSGlueDDL.Table)
........
}
}
class ParquetTransformer extends Transformer{
override def getTransformSettings: TransformSettings = {
val transformSettings = new TransformSettings {
override def getOuputFormat: String = {
"parquet"
}
override def getOuputIndex(table: AWSGlueDDL.Table): Option[String] = {
table.StorageDescriptor.SerdeInfo.Parameters.get("parquet.column.index.access")
}
}
}
}
Is there a way to avoid creating a brand new object of TransformSettings in Transfomer class every time this is called?
Also is there a way to rewrite the code using Scala value class?
As #Dima proposed in the comments try to make TransformSettings a field / constructor parameter (a val) in the class Transformer and instantiate them outside
class TransformSettings{
def getOuputFormat: String = {
"orc"
}
def getOuputIndex(table: AWSGlueDDL.Table): Option[String] = {
table.StorageDescriptor.SerdeInfo.Parameters.get("orc.column.index.access")
}
}
class Transformer(val transformSettings: TransformSettings) {
def posttransform(table: AWSGlueDDL.Table): DataFrame ={
val indexAccess = transformSettings.getOuputIndex(table: AWSGlueDDL.Table)
???
}
}
val parquetTransformSettings = new TransformSettings {
override def getOuputFormat: String = {
"parquet"
}
override def getOuputIndex(table: AWSGlueDDL.Table): Option[String] = {
table.StorageDescriptor.SerdeInfo.Parameters.get("parquet.column.index.access")
}
}
class ParquetTransformer extends Transformer(parquetTransformSettings)
You don't seem to need value classes (... extends AnyVal) now. They are more about unboxing, not about life-cycle management. TransformSettings and Transformer can't be value classes because they are not final (you're extending them in class ParquetTransformer extends Transformer... and new TransformSettings { ... }). By the way, value classes have many limatations
https://failex.blogspot.com/2017/04/the-high-cost-of-anyval-subclasses.html
https://github.com/scala/bug/issues/12271
Besides value classes, there are scala-newtype library in Scala 2 and opaque types in Scala 3.

Implement a new feature with loose coupling

trait paymentTasks{
def calculatePayment()
def getData()
}
class paymentcalculator{
override def calculatePayment() ={
//Implementation }
}
override defGetData() ={
}
}
How do I call the method to keep the code less dependent and don't want to use new keyword
class MyApp{
val payment = new paymentcalculator
//I don't want to instantiate like this wants this to be decoupled
}
Please suggest how do I implement this ,also new Changes in future can be done without changing existing code.Also,suggest if doing this functionally would be more effective
If you want compile-time selection then just put the code into an object
trait PaymentTasks {
def calculatePayment()
def getData()
}
object PaymentCalculator extends PaymentTasks {
def calculatePayment() = ???
def getData() = ???
}
class MyApp {
val payment = PaymentCalculator.calculatePayment()
}
If you want run-time selection than the best way is to use dependency injection and create the payment object at the top level and pass it down to the code that requires it.
object SimplePaymentCalculator extends PaymentTasks
object ComplexPaymentCalculator extends PaymentTasks
class MyApp {
def myImplementation(tasks: PaymentTasks) = {
val payment = tasks.calculatePayment()
}
val payment =
if (???) {
SimplePaymentCalculator
} else {
ComplexPaymentCalculator
}
myImplementation(payment)
}

What are the implications of nesting an akka Actor class in an object to the members of the class?

I'm new to scala and akka and I came across code that looked something like this:
object Foo extends App {
class Bar extends Actor with ActorLogging{
val graph: TitanGraph = _
private def setGraph() = {
graph = TitanFactory.open(...)
}
setGraph()
...
}
def startBar() {
val barSystem = ActorSystem("BarSystem")
for(i <- 0 until numActors) {
val barActor = barSystem.actorOf(Props[Bar], name="BarActor" + i)
...
barActor ! Start
}
}
startBar
}
Does this have any effect on performance as compared to?:
object Foo extends App {
override def main(args: Array[String]): Unit = {
val barSystem = ActorSystem("BarSystem")
for(i <- 0 until numActors) {
val barActor = barSystem.actorOf(Props[Bar], name="BarActor" + i)
...
barActor ! Start
}
}
}
object Bar {
val graph: TitanGraph = _
private def setGraph() = {
graph = TitanFactory.open(...)
}
setGraph()
def props = Props[Bar]
...
}
class Bar extends Actor with ActorLogging{
...
}
In the first case, you're creating multiple instances of the graph but in the second case, I assume that you're using a single instance shared across workers?
Also, I read somewhere that it is good practice to keep the Actor's props factory in the companion object but not sure if the previous code breaks actor encapsulation or if it affects performance at all.
Whether you place an Actor inside an object or outside does not change anything besides the class file name. Concerning sharing a single Actor object instance, that is illegal and will not work, but luckily you cannot easily fall into this trap.

Play framework + Scala: Inject dependency using Action Composition

I'm setting up a Play! app for our API. This API encapsulates different services. I want to inject these services inside an action but only the ones required for that particular endpoint. Something like:
object Application extends Controller {
def index = (UsersAction andThen OrdersAction) {
// boom UsersService and OrdersService is available here
for {
users <- usersService.list
orders <- ordersService.list
} yield "whatever"
}
}
I've been playing with this idea and using ActionTransformers I'm able to transform the incoming Request to a request that has a given service, but I don't see how I can make that generic enough so I can compose these actions in an arbitrary order without create ActionTransformers for all the possible combinations of WrapperRequests.
Maybe action composition is not the best way to achieve this. I'm all ears.
Thank you
UPDATE:
To clarify, the code above is pseudocode, the ideal scenario, in which usersService and ordersService are made available to that scope (implicits? I don't know). If that's not possible, then whatever adds the less amount of noise of top of that sample that would work. Thanks
The closest I could get to your question is this:
def index =
new UsersAction with OrdersAction {
def body =
for {
users <- userService.list
orders <- orderService.list
} yield Ok("whatever")
}
The implementation is quite straight forward
trait CustomAction extends Action[AnyContent] {
def body: Future[Result]
def apply(request: Request[AnyContent]): Future[Result] = body
val parser = BodyParsers.parse.anyContent
}
trait UsersAction extends CustomAction {
val userService: UserService = ???
}
trait OrdersAction extends CustomAction {
val orderService: OrderService = ???
}
These are the other parts I used to get it to compile:
trait User
trait Order
trait UserService {
def list: Future[Seq[User]]
}
trait OrderService {
def list: Future[Seq[Order]]
}
You can inject by guice, spring or what you want.
Example for guice.
Just change the object to class:
class Application #Inject(userAction:UsersAction,ordersAction:OrdersAction) extends Controller {
def index = (UsersAction andThen OrdersAction) {
// boom UsersService and OrdersService is available here
for {
users <- usersService.list
orders <- ordersService.list
} yield "whatever"
}
}
You have to override in Global:
object Global extends GlobalSettings{
private lazy val injector = Guice.createInjector(new CommonModule)
override def getControllerInstance[A](clazz: Class[A]) = {
injector.getInstance(clazz)
}
}
class CommonModule extends AbstractModule{
protected def configure() {
bind(classOf[UsersAction]).to(classOf[UsersActionImpl])
bind(classOf[OrdersAction]).to(classOf[OrdersActionImpl])
}
}
In route file add # to controllers:
GET /service #controllers.Application.index

idiomatic property changed notification in scala?

I'm trying to find a cleaner alternative (that is idiomatic to Scala) to the kind of thing you see with data-binding in WPF/silverlight data-binding - that is, implementing INotifyPropertyChanged. First, some background:
In .Net WPF or silverlight applications, you have the concept of two-way data-binding (that is, binding the value of some element of the UI to a .net property of the DataContext in such a way that changes to the UI element affect the property, and vise versa. One way to enable this is to implement the INotifyPropertyChanged interface in your DataContext. Unfortunately, this introduces a lot of boilerplate code for any property you add to the "ModelView" type. Here is how it might look in Scala:
trait IDrawable extends INotifyPropertyChanged
{
protected var drawOrder : Int = 0
def DrawOrder : Int = drawOrder
def DrawOrder_=(value : Int) {
if(drawOrder != value) {
drawOrder = value
OnPropertyChanged("DrawOrder")
}
}
protected var visible : Boolean = true
def Visible : Boolean = visible
def Visible_=(value: Boolean) = {
if(visible != value) {
visible = value
OnPropertyChanged("Visible")
}
}
def Mutate() : Unit = {
if(Visible) {
DrawOrder += 1 // Should trigger the PropertyChanged "Event" of INotifyPropertyChanged trait
}
}
}
For the sake of space, let's assume the INotifyPropertyChanged type is a trait that manages a list of callbacks of type (AnyRef, String) => Unit, and that OnPropertyChanged is a method that invokes all those callbacks, passing "this" as the AnyRef, and the passed-in String). This would just be an event in C#.
You can immediately see the problem: that's a ton of boilerplate code for just two properties. I've always wanted to write something like this instead:
trait IDrawable
{
val Visible = new ObservableProperty[Boolean]('Visible, true)
val DrawOrder = new ObservableProperty[Int]('DrawOrder, 0)
def Mutate() : Unit = {
if(Visible) {
DrawOrder += 1 // Should trigger the PropertyChanged "Event" of ObservableProperty class
}
}
}
I know that I can easily write it like this, if ObservableProperty[T] has Value/Value_= methods (this is the method I'm using now):
trait IDrawable {
// on a side note, is there some way to get a Symbol representing the Visible field
// on the following line, instead of hard-coding it in the ObservableProperty
// constructor?
val Visible = new ObservableProperty[Boolean]('Visible, true)
val DrawOrder = new ObservableProperty[Int]('DrawOrder, 0)
def Mutate() : Unit = {
if(Visible.Value) {
DrawOrder.Value += 1
}
}
}
// given this implementation of ObservableProperty[T] in my library
// note: IEvent, Event, and EventArgs are classes in my library for
// handling lists of callbacks - they work similarly to events in C#
class PropertyChangedEventArgs(val PropertyName: Symbol) extends EventArgs("")
class ObservableProperty[T](val PropertyName: Symbol, private var value: T) {
protected val propertyChanged = new Event[PropertyChangedEventArgs]
def PropertyChanged: IEvent[PropertyChangedEventArgs] = propertyChanged
def Value = value;
def Value_=(value: T) {
if(this.value != value) {
this.value = value
propertyChanged(this, new PropertyChangedEventArgs(PropertyName))
}
}
}
But is there any way to implement the first version using implicits or some other feature/idiom of Scala to make ObservableProperty instances function as if they were regular "properties" in scala, without needing to call the Value methods? The only other thing I can think of is something like this, which is more verbose than either of the above two versions, but is still less verbose than the original:
trait IDrawable {
private val visible = new ObservableProperty[Boolean]('Visible, false)
def Visible = visible.Value
def Visible_=(value: Boolean): Unit = { visible.Value = value }
private val drawOrder = new ObservableProperty[Int]('DrawOrder, 0)
def DrawOrder = drawOrder.Value
def DrawOrder_=(value: Int): Unit = { drawOrder.Value = value }
def Mutate() : Unit = {
if(Visible) {
DrawOrder += 1
}
}
}
I couldn't claim that this is a canonical property change framework in Scala, but I've used a class like this before:
abstract class Notifier[T,U](t0: T) {
import java.util.concurrent.atomic.AtomicReference
import scala.actors.OutputChannel
type OCUT = OutputChannel[(U,AtomicReference[T])]
val data = new AtomicReference[T](t0)
def id: U
protected var callbacks = Nil:List[T => Unit]
protected var listeners = Nil:List[OCUT]
def apply() = data.get
def update(t: T) {
val told = data.getAndSet(t)
if (t != told) {
callbacks.foreach(_(t))
listeners.foreach(_ ! (id,data))
}
}
def attend(f: T=>Unit) { callbacks ::= f }
def attend(oc: OCUT) { listeners ::= oc }
def ignore(f: T=>Unit) { callbacks = callbacks.filter(_ != f) }
def ignore(oc: OCUT) { listeners = listeners.filter(_ != oc) }
}
The motivation for creating this class was that I wanted a flexible thread-safe way to react to changes, which this provides (as it delivers both callbacks and can push messages to actors).
It seems to me--unless I'm misunderstanding exactly what you want because I haven't had occasion to learn the WPF/Silverlight stuff--that this can implement everything you want and more.
For example,
class IDrawable extends SomethingWithOnPropertyChanged {
val drawOrder = new Notifier[Int,Symbol](0) { def id = 'DrawOrder }
val visible = new Notifier[Boolean,Symbol](false) { def id = 'Visible }
drawOrder.attend((i:Int) => OnPropertyChanged(drawOrder.id))
def mutate {
if (visible()) drawOrder() += 1
}
}
should be roughly equivalent to what you want. (Again, I'm not sure how flexible you want this to be; you could create a set of symbol -> notifier mappings that you would look up with an apply method so the target would have an easier time of doing something when it gets the DrawOrder symbol.)
The only significant difference from your usage is that the Notifier uses its apply/update methods to save boilerplate; you don't have to write def x and def x_= methods every time, but you do have to use () for access.