0

I have a persistent actor which holds some values. I need to get some filtered ones of them. So, I have two ways:

1) Create new message say

GetValuesWithNameAndAgeGraterThan(name: String, age: Int)

pro: immutable, orthodox :) contra: the problem here is that logic leaks into persistent actor which should be responsible only for keeping and providing data and ya, this case is exactly fits to providing data definition. But why should it know about "name" and "age" of value it keeps?! And since tomorrow I would be needed to add more and more messages which would become a mess at the end.

2) Create generic message with filtering predicate

Filter(p: Value => Boolean)

pro: single, scalable, immutable when used properly contra: I see the only problem when someone does

val ages: mutable.Seq[Int]
persistor ? Filter(v => ages.contains(v.age))
ages += 18
ages += 33

but we are usually using immutable values in Scala! and also it would be unnatural to try to persist lambda, but we use it for read only!

So, what do you think?!

Igor Yudnikov
  • 434
  • 1
  • 6
  • 14

1 Answers1

1

Never do follow the second approach! The first is valid, but id change this a little bit. You could initially agree on some contract for stored data, e.g might be an Enumeration where each value carries a value type. So you modify your message with

GetValueForCondition(conditions: Seq[DataType, filter: Value => Boolean]), where DataType is an Enumeration value specifying the name and type of data and the filter defines the condition on the value. This way you can specify generic queries for entities, which is reusable for requests to other data storing actors. You could also include a Boolean indicating for each data field whether it has to be set for an entity to be returned in the result. In case you store all those information belonging to one entity (e.g name, age,...) in an Entity object (e.g your persistent actor has some storage for multiple such Entities), you could implement the filtering generically within that Entity class, and ur data providing actor is free of this logic.

awagen
  • 236
  • 2
  • 8
  • Didn't understood. What would be in DataType? Say I keep Seq of Persons(name: String, age: Int) at persister, what would be DataType? And if you are still passing predicate, what is the difference with second approach? Do you mean Person => Boolean? – Igor Yudnikov Apr 10 '19 at 07:09
  • The above was just to have a general solution for requesting entities and having some predefined datatypes to make requesting generic. So for the Persons example above, DataType would be identifier: String = "name", valueType = String and for age accordingly "age" with valueType Int. But you are right that in case youre only having Persons to request, thats more than you need. I rather thought you need a system, e.g where PersonsEntity is basically a subtype of generic Entity which can hold multiple DataTypes with their respective values. This would easily extend to other entities. – awagen Apr 10 '19 at 08:32
  • The difference to second approach is also that you do not include any mutable structure in your message, which you should not do. Rather, this there just the type and the filter to be applied on it is defined. I just see there was a typo, I meant ```GetValueForCondition(conditions: Seq[(type: DataType, filter: Value => Boolean)]) ``` – awagen Apr 10 '19 at 08:34
  • ))) ok, got it. It's misunderstanding. Of course passing mutable stuff into message is absolutely veto, I've mentioned the approach with passing predicate into message in general. – Igor Yudnikov Apr 10 '19 at 09:21
  • 1
    I do not see a problem with your second approach if you just send immutables, which also works there – awagen Apr 10 '19 at 09:22