In Fantom's Actor framework, messages that are not immutable are automatically serialized for you, as specified in the documentation.
This automatic serialization has tripped me up a couple of times now. If I forget to put ".toImmutable" on the end of my Map literal, serialization happens silently without me intending to do that.
I would prefer that there be some way to optionally specify that message serialziation is disabled. Then mutable messages would throw an error immediately when you attempt to send them (rather than manifesting themselves later on as an arcane bug :-).
Maybe we could have an entry in a properties file somewhere down undereath the /etc directory?
SlimerDudeFri 3 Jul 2015
Hi Mike,
If a serialisation switch is to be put anywhere then I agree that a property in sys.props is a good place for it.
But should the switch exist, would we not then run into compatibility problems? Each library would have to dictate which configuration it works with, which may be incompatible with other libraries.
Sure, all Fantom libraries and programs could just work to the lowest common denominator, but that kinda defeats the point of having a switch, no? :(
I don't know how many message maps you have, but as an interim workaround, you could put your maps inside a const class - that would then force you to have immutable objects.
But that's just my initial thoughts...
brianFri 3 Jul 2015
I think supporting serialization implicitly in the message passing was a huge mistake. It has the potential to silently destroy your performance. And if you really need to use serialize it is still trivial to do it yourself and pass the serialized Str back and forth. I have never used serialization in any actors in real code.
So I would really like to come up with a plan to deprecate that feature.
We could just turn that feature off, and require people to rework their message passing to explicitly turn messages into a string.
Or we could provide a hook in Actor to allow it on a per actor basis, but if we default it to be off by default that is still a code change.
I guess a global property in sys/config.props might be one way to do it to give people time to change their code. So that might be best solution.
elyashivSat 4 Jul 2015
What about just using a warning at compile time? This way you don't have compatibility issues, and you can find the point where you did a mistake.
mikeSat 4 Jul 2015
I like that idea elyashiv. There would just be a one-line warning for each site at compile time.
I don't know if Fantom has @SuppressWarnings annotations, but if it does then perphaps one could do @SuppressWarnings("mutableMessage") or some such. That way if you really wanted to use serialization you could hide the message.
And if you wanted to see a bigger message at compile time, there could be a compiler argument sort of like the java compiler: "-Xlint:mutableMessage".
Or maybe there could even be a compile time argument to disallow message serialization.
andySun 5 Jul 2015
I'd just cut it off cleanly so we're not left with cruft. But I would be ok making it a warning for one build - but then compiler error for the following.
brianSun 5 Jul 2015
It can't really be checked effectively at compile time because the API uses Obj generically, and even at call sites to send things are often just Obj.
I agree with Andy, that best solution is to just deprecate the serialization, output a warning for a grace period, then after a while remove that feature. Like I said, its a pretty easy fix to pass Strs and do the serialization yourself.
mikeMon 6 Jul 2015
Well it certainly works for me if we deprecate it. I'd rather just use Fantom's support for immutability.
brianFri 10 Jul 2015
If you use serialized msg, you will get a big warning to stdout now. After a few months or so, I will remove support completely
brianFri 10 Jul 2015
I remember now why I didn't do this before - its because I was using serialization for storing web sessions in Wisp. That design was outrageously expensive compared to using immutable maps. So I changed the behavior of WebSession to require immutable values - that allows sessions to be cached in memory much more efficiently. I also deprecated WebSession.map in favor of get, set, each, and remove which allows more control for mutating of the backing store map.
SlimerDudeSun 12 Jul 2015
Could the new _safe method attempt to call toImmutable() before serialisation? For that is usually what is wanted, and would solve Mike's problem (and any other caller) of forgetting to call toImmutable() themselves.
brianSun 12 Jul 2015
The AtomicRef class does not do that. By convention the compiler does it when setting atomic fields, but APIs at runtime does not do it implicitly. Whatever we do, we should do it consistently. No sure I have a strong opinion one way or the other
ahhatemSun 18 Mar 2018
Hi All, may I ask why is the serialization warning printed to stdout not stderr?
mike Thu 2 Jul 2015
In Fantom's Actor framework, messages that are not immutable are automatically serialized for you, as specified in the documentation.
This automatic serialization has tripped me up a couple of times now. If I forget to put ".toImmutable" on the end of my Map literal, serialization happens silently without me intending to do that.
I would prefer that there be some way to optionally specify that message serialziation is disabled. Then mutable messages would throw an error immediately when you attempt to send them (rather than manifesting themselves later on as an arcane bug :-).
Maybe we could have an entry in a properties file somewhere down undereath the /etc directory?
SlimerDude Fri 3 Jul 2015
Hi Mike,
If a serialisation switch is to be put anywhere then I agree that a property in
sys.props
is a good place for it.But should the switch exist, would we not then run into compatibility problems? Each library would have to dictate which configuration it works with, which may be incompatible with other libraries.
Sure, all Fantom libraries and programs could just work to the lowest common denominator, but that kinda defeats the point of having a switch, no? :(
I don't know how many message maps you have, but as an interim workaround, you could put your maps inside a
const
class - that would then force you to have immutable objects.But that's just my initial thoughts...
brian Fri 3 Jul 2015
I think supporting serialization implicitly in the message passing was a huge mistake. It has the potential to silently destroy your performance. And if you really need to use serialize it is still trivial to do it yourself and pass the serialized Str back and forth. I have never used serialization in any actors in real code.
So I would really like to come up with a plan to deprecate that feature.
We could just turn that feature off, and require people to rework their message passing to explicitly turn messages into a string.
Or we could provide a hook in Actor to allow it on a per actor basis, but if we default it to be off by default that is still a code change.
I guess a global property in sys/config.props might be one way to do it to give people time to change their code. So that might be best solution.
elyashiv Sat 4 Jul 2015
What about just using a warning at compile time? This way you don't have compatibility issues, and you can find the point where you did a mistake.
mike Sat 4 Jul 2015
I like that idea elyashiv. There would just be a one-line warning for each site at compile time.
I don't know if Fantom has @SuppressWarnings annotations, but if it does then perphaps one could do @SuppressWarnings("mutableMessage") or some such. That way if you really wanted to use serialization you could hide the message.
And if you wanted to see a bigger message at compile time, there could be a compiler argument sort of like the java compiler: "-Xlint:mutableMessage".
Or maybe there could even be a compile time argument to disallow message serialization.
andy Sun 5 Jul 2015
I'd just cut it off cleanly so we're not left with cruft. But I would be ok making it a warning for one build - but then compiler error for the following.
brian Sun 5 Jul 2015
It can't really be checked effectively at compile time because the API uses Obj generically, and even at call sites to send things are often just Obj.
I agree with Andy, that best solution is to just deprecate the serialization, output a warning for a grace period, then after a while remove that feature. Like I said, its a pretty easy fix to pass Strs and do the serialization yourself.
mike Mon 6 Jul 2015
Well it certainly works for me if we deprecate it. I'd rather just use Fantom's support for immutability.
brian Fri 10 Jul 2015
If you use serialized msg, you will get a big warning to stdout now. After a few months or so, I will remove support completely
brian Fri 10 Jul 2015
I remember now why I didn't do this before - its because I was using serialization for storing web sessions in Wisp. That design was outrageously expensive compared to using immutable maps. So I changed the behavior of WebSession to require immutable values - that allows sessions to be cached in memory much more efficiently. I also deprecated WebSession.map in favor of get, set, each, and remove which allows more control for mutating of the backing store map.
SlimerDude Sun 12 Jul 2015
Could the new
_safe
method attempt to calltoImmutable()
before serialisation? For that is usually what is wanted, and would solve Mike's problem (and any other caller) of forgetting to calltoImmutable()
themselves.brian Sun 12 Jul 2015
The AtomicRef class does not do that. By convention the compiler does it when setting atomic fields, but APIs at runtime does not do it implicitly. Whatever we do, we should do it consistently. No sure I have a strong opinion one way or the other
ahhatem Sun 18 Mar 2018
Hi All, may I ask why is the serialization warning printed to stdout not stderr?