Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Honoring the IMultithreaded gaurantees forces ChannelFactory to store a Map from channel class name to channel instance. It also requires ChannelFactory to lock on channel instantiation while it detects whether the requested channel is IMultithreaded, whether it is in the Map if it is, and while it instantiates it if it either isn't IMultithreaded or is IMultithreaded but is not yet instantiated. This results in ChannelFactory serializing (with lock acquisition and release) instantiation of all channels, not just IMultithreadeds. Were ChannelFactory not supporting IMultithreaded, this locking would not be required and channel instantation could be serviced by multiple threads concurrently.

Supporing IMultithreaded also complicates ChannelFactory, with its logic tree and instanceof checks on the channel being instantiated to see whether and what IChannel-implementing-wrapper to use around the channel.

Since IMutlithreaded* is a published and commonly used interface, uPortal cannot in the near term realize the efficiencies of dropping support for this interface.

IMultithreaded makes it hard to talk about uPortal

I don't mean this in jest. Writing this document is hard. Where I'd like to talk about "channel instances", I can't, and instead have to invent "channel usages", because IMultithreaded uses a single object instance with a keyed internal map to represent many boxes across many users' layouts. IChannel uses one object instance to represent one box in one user's layout. This is more articulable, easier to understand. Simplicity is worth something.

Alternatives to using IMultithreaded

IMultithreaded re-implements statics

IMultithreaded provides a way to share state across the objects backing boxes rendered in users layouts (the usages of the channel). Using IMultithreaded is entirely equivalent to using IChannel with static fields for state desired to be shared across all instances of the channel. Any given IMultithreaded* channel can be refactored as an IChannel with its instance fields become static fields.

Share services, not channel instance state

Including a Map with everyone else's ChannelState objects doesn't help IMultithreaded service my request. Everyone else's state is irrelevant to my request and it's just junk to be carefully ignored in a threadsafe, synchronized way.

However, it is entirely plausible that there are some things that can be shared across channel instances. An efficiency might be to lookup a portal.properties property once rather than once per channel instance. Or an Announcements channel implementation should be backed by an Announcements service rather than stuffing your institution's entire Announcements infrastructure into the channel implementation.

And these services can be shared. They can be grabbed from Factories using static initializers if they need to be shared statically. They can be grabbed from Spring if you'd like to declaratively configure them. They could even be grabbed from JNDI. Writing traditional IChannels, rather than IMultithreadeds, does not by any means mean that your channels cannot share the state and services they ought to share. Avoiding IMultithreaded does, however, help channels to avoid sharing state they don't need to share, state that just gets in the way.

Summary

What makes this even more clear-cut for me is that we haven't written a single channel that benefits from being implemented as IMultithreaded*. It is clear that we should discourage implementation of channels as IMultithreaded*, and I think deprecating the interfaces is the clearest way to communicate this without ambiguity.

...