As far as I can tell, the special properties of completing a constructor
in the JLS memory model are:
1. A happens-before edge from the end of the constructor to the start of
a finalizer. (17.4.5)
2. The guarantee that any thread that only sees a reference to an object
after the end of the constructor will see the correctly initialized
values of all final fields. (17.5)
The special issue with final fields is that implementations have freedom
to optimize access to final fields in ways that are not permitted for
non-final fields. Strategies for thread safety that work for non-final
fields do not necessarily work for final fields. The requirement for
final field safety is that the constructor end before another thread
accesses the newly constructed object.
Calling a start() method after construction if the class implements a
new interface seems to me to be harmless, backwards compatible, and
useful. It enables the simplest and most direct way of preventing access
to the new object by another thread during construction.
The roadmap issue is whether it should be required, and if so the level
of enforcement. For example, there is no reason to require it if the
class does not declare any final fields.
Incidentally, and as a detail, "Commission" does not immediately make me
think of having a start() method that should be called after
construction. If you do go this way, the name needs thought. "Startable"
would be more obvious, more memorable, more likely to be found on
searches, and more compatible with familiar interface names such as
"Cloneable" and "Iterable".
Patricia
On 12/18/2013 2:18 AM, Peter wrote:
Well, now seems like a good time to have the conversation.
Yes there are other ways, but I haven't seen one safe implementation yet, so...
Does someone have a better way to solve this problem, has someone already
solved this problem I'm unaware of that we can adopt, or is there a way that's
more satisfactory?
If not, is there something objectionable with the Commission interface and if
so, how can we fix it?
The SEVERE log message is logged by the River start package, other containers
or frameworks can choose whether or not to do so, but I'd encourage them to do
something similar, yes we can change it to WARN.
A much harsher option is to throw an exception during export which breaks
backward compatibility.
Regards,
Peter.
----- Original message -----
"org.apache.river.api.util.Commission is an interface services should
implement"
If it's a SHOULD, not a MUST, chucking out a SEVERE is incorrect logger
behaviour IMO. You could issue a WARN if you like but for even that I'd
say you need to provide a roadmap explaining why the warning and what you
intend to do in future and what you expect of service writers such as
myself.
Commission, at least from my point of view, is your means (maybe the
River community's - did you ask us?) for satisfying your needs in
respect of the JMM. As we've discussed previously, there are other ways
too and they work and they are safe if you know what you're doing. Your
contention was that most don't know what they're doing hence,
presumably, Commission.
So the thing is, you are seemingly on a road to asserting more structure
(gosh, a standard?) on the way people write their services. If so, you'd
best start flagging that honestly and openly via a roadmap, deprecation
and such/whatever rather than sticking out logger messages with no clear
guidance and at the cost of a certain amount of nuisance (no admin I know
likes SEVERE's being logged for something which isn't critical cos it's
noise they don't want in log files).
And of course, we all know that when some entity asserts a standard or
requirement on others for entry, they may choose not to enter. Does this
help your community or hinder it? The answer to that is, it depends. On
what? Have you asked or tested? How have you tested? What would be
considered validation or lack of support?
I am not out to flame or troll rather I want to see this community
demonstrating good behaviour and I'm not feeling like what's going on
around Commission (what is that big change in version number really
saying?) is such.
On 18 December 2013 08:52, Peter <j...@zeus.net.au> wrote:
Just to clarify org.apache.river.api.util.Commission is an interface
services should implement, I would encourage all container projects to
pick up the interface and make suggestions for improvement if there
are any issues.
Interface Commission {
void start () throws Exception;
}
It's called after JMM safe construction to allow the service to start
any threads and be exported.
Regards,
Peter.
----- Original message -----
The way that services are instantiated and setup is an implementation
detail. When I think of compatibility I think of the API and the
lookup methods. We think of compatibility from a client point of
view. From the client point of view, using a service looks like
this:
- Use multicast of unicast discovery to find one or more
ServiceRegistrar instances - Call lookup(…) on one or more of
these instances to get a set of service candidates - Choose a
candidate and prepare() it using a ProxyPreparer, to yield a usable
service proxy. - Make calls on it. Ideally hang on to this
proxy instance, so you can skip the discovery and lookup next time
you need it. - If the call fails, repeat the lookup (and possibly
discovery) til you get a proxy that works.
Nowhere does the client need to know whether the service instance is
started up using the “com.sun.jini.start” mechanism, your Commission
interface, some other IOC container (Rio, Harvester, Seven or
RiverContainer) or some unknown mechanism that starts with a static
main() method.
JSK2.0 was 2.0 because of the introduction of the proxy verification
mechanisms, as well as JERI. Absent some new client usage
mechanism, River doesn’t need to go to 3.0.
Cheers,
Greg.
On Dec 17, 2013, at 1:58 PM, Peter <j...@zeus.net.au> wrote:
I think changing services to use safe construction techniques is
enough to cause the version jump.
At this point I've allowed services to continue unsafe construction
practices, while logging a SEVERE warning when the Commission
interface isn't implemented, rather than fail.
This is a fundamental change to the way services are written.
Regards,
Peter.
----- Original message -----
Assuming that there aren’t major incompatibilities, I think that
would be a “minor” version change according to our versioning
policy, so we’d be looking at the “2.3” branch rather than a
“3.0” release.
I’m still unnerved by the massive amounts of changes to both
code and tests in the qa_refactor branch, as well as the
apparent instability of the code, although that seems to be
improving. In the next few weeks I’m going to try and setup
a cross-test case, to see what the “2.2” tests say about the
potential “2.3” release and vice-versa.
I think what I’d really like to see is an incremental approach
where we update limited components of the “2.2” branch, one at a
time. Is there anything that we could pull out piecemeal?
Maybe it
would
make sense to split out the infrastructure services, like Reggie,
Mahalo, and Outrigger into different sub-projects that could be
updated separately?
Any thoughts?
Greg.
On Dec 17, 2013, at 5:03 AM, Peter <j...@zeus.net.au> wrote:
When the qa_refactor branch stabilises, I plan to merge trunk
and provide a beta release for client compatibility testing.
Changes made have been focused on making our code thread safe,
there are significant changes internally, the public api
remains focused on backward compatibility, however it is
advisable that client services adopt new safe construction
techniques for services and implement the new Commission
interface.
What's a suitable test period for client testing?
Regards,
Peter.