Skip to content
This repository has been archived by the owner on Feb 20, 2019. It is now read-only.

Fix #415 - initialization of pickler registry when switching runtime strategies #416

Merged
merged 1 commit into from
May 2, 2016

Conversation

jvican
Copy link
Member

@jvican jvican commented Apr 22, 2016

  • Now, every time we change the runtime, we pass its state if the
    runtime allows lookups. The state is composed by the registered
    picklers and unpicklers.
  • Add documentation for every new method.
  • Remove some unused imports.

/cc @jsuereth

@jvican jvican changed the title Add tests that show bug explained in #415 Fix #415 - initialization of pickler registry when switching runtime strategies Apr 22, 2016
@jvican
Copy link
Member Author

jvican commented Apr 25, 2016

Shall we merge this @jsuereth?

@jsuereth
Copy link
Contributor

Sorry for delay, a few comments coming.

@jvican
Copy link
Member Author

jvican commented Apr 25, 2016

No worries, I do understand that you're busy 😄. Thanks for your time reviewing this!

*/
def replaceRuntime(r: PicklingRuntime): Unit = {
if(r.picklers.isLookupEnabled) {
currentRuntime.picklers.dumpStateTo(r.picklers)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick note: This is not thread safe. It may be ok to assume that we'll only ever swap runtimes on one thread, but if the issue is somehow the runtime is being created on one thread and replaced on another, this won't work.

I think in the event there are multiple instantiation threads and this function hasn't completed first, we're already screwed, so it's probably ok as is, we just need to heavily document how to safely override the runtime and instantiate picklers.

E.g. the documentation for how to repalce runtime right now shows how to create a new object to contain your entire "protocol". That's part 1 to making sure this is safe. Part #2 is to make sure you pre-allocate that object in your "main" thread before you spawn sub-threads.

I had originally punted a bit on this problem, but given we're adding this functionality (which does need to be there), we should really document this problem and possible user solutions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I didn't even thought about thread safety.

As you have correctly pointed out, the real problem is that we're not pre-allocating the object PicklingProtocol before using it. I forgot to explain that, my apologies. However, we cannot rely on the user to do this, since even if the pickling protocol is imported in scope, it won't be preallocated. One has to explicitly pull something from the protocol, like implicitly[Pickler[List[Int]]]. Then, it gets initialized and the runtime changes.

Since we cannot rely on the user always doing that, I implemented this ugly solution. Yet it is the only one that will work no matter what the user decides to do. We should probably work more on the thread safety. Do you think it would be a good idea to mark this method as synchronized? I'd do it just to shape a more robust api and make explicit the fact that it's not thread-safe. Anyway, as the user will rarely use it, the synchronized overhead will be minimal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue with synchronizing this method is you'd need to ALSO synchronize all other access to the pickler registry, whcih slows down general runtime. We already use thread-safe lookup (in the eventual consistency version of thread safety), so I'd hate to furtehr slow down lookup with a full up synchronize.

There are ways to force things to initialize without forcing implicitly, specifically if you use the "cake" approach for your default picklers. It's not pretty, but it is workable.

In any case, as i said, I think what you have is fine, we just need to document WHY we think it's fine and where it is not fine :). As long as it's documented, users may be surprised, but able to cope. that's better than surprised and have no idea how to resolve the issue.

The best case would be if we had a legitimate solution to the problem. Given the current architecture, I think we do not, but I'm happy to hear alternative ideas :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this is good for a short-term solution, but we should think about a new "cake" approach, because the way to customize the runtime is not sleek. Especially if this runtime strategy depends on implicits that the user may put into scope (like StaticOnly, I'll open an issue to explain what I mean by this).

But, atm, I agree that we should stick with this and greatly document it. I do not see any other alternative solution.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree :) Looking forward to readi gthe bug.

@jsuereth
Copy link
Contributor

Ok, not ready to merge, but I like the direction.

In terms of registering picklers again from maps, there are solutions to that which I can show you if needed. As I said before, best to avoid existential types until you need them, generally.

@jvican
Copy link
Member Author

jvican commented May 2, 2016

This is again for review 😄

type PicklerGenerator = FastTypeTag[_] => Pickler[_]
type UnpicklerGenerator = FastTypeTag[_] => Unpickler[_]

type PicklerGen = FastTypeTag[_] => Pickler[_]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see here, I was inconsistent in my existential usage (reality, I think I was just moving code around and never cleaned it up :) ).

@jsuereth jsuereth merged commit 310f1b0 into scala:0.11.x May 2, 2016
@jvican jvican added this to the 0.11.0-M1 milestone May 9, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants