[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Orekit Developers] Is serialization of propagators really useful
Evan Ward <evan.ward@nrl.navy.mil> a écrit :
Hi all,
Hi Evan,
MAISONOBE Luc wrote:
There are two reasons for the current behaviour for
FactoryManagedFrames. The first reason was that we really need to
have a single root hierarchy, so when deserializing a frame we have
to plug it in the existing frame, we cannot let it create an
independent tree by deserializing all its ancestors. The second
reason was that we wanted to avoid creating too many copies of
similar frames. These instances are not singleton per se (and don't
need to) but they have some characteristics of singleton, only for
memory consumption purposes. However, since now the data are hold
by TimeStampedCache which is not serializable and the same cache
can be shared by many instances (even in different thread, as it
was created specifically for this purpose), the second reason about
memory consumption problems could be ignored. So you are right, it
is worth looking at what we want to save.
I think the single root hierarchy is a good design. The issue with
serialization is that it provides "hidden" constructors that are
often overlooked. I've attached a small program that creates a
second root frame using serialization. Interestingly, it works even
with a SecurityManager in place. I got the idea from Joshua Bloch's
chapter on Serialization in Effective Java, which explains this and
other problems with serialization. I think the proxy objects
strategy that you suggested would fix this problem as long as
readObject() throws an exception. The proxy strategy might make it
harder to serialize subclasses because they will repeat their
parents serialized form in addition to their new information.
Your example is really interesting. A side effect of the new
implementation of findCommon implies that this example does not
trigger an NPE anymore even when two different tree roots are present.
In fact, the common frame is considered to be the parent of the two
different GCRF, which is null. So the transform computation goes
through all frames up to root, but it handles this gracefully! The
reason for this unexpected good behaviour is that despite the root has
no parent, it has a transform from this non-existing parent set up and
this transform is identity. Hence when we combine all transforms we
end up by combining the identity between each root and its null
parent. So both combined transforms from->common and to->common are
valid and can be combined together.
Well, I don't think we can rely on this side effect, it's rather ugly...
I am on the fence about analyzing the rest of the example. Getting the
two roots implies setting up explicit code for that (picking up the
frame from within the readResolve method), and I don't think we could
protect against such practice. As another example, users could reset
the parent point to null using reflection. Protecting against errors
(i.e. users getting two roots without explicit coding) is of course
the thing we should prevent.
I'll take a look at making sure at least the predefined frames are
serialized using only a proxy object storing their identifier only,
this will be a first step towards increasing robustness.
Thomas Neidhart wrote:
Regarding the serialization of immutable objects: I think Evan made
a good point, that the context in which an object is created (e.g.
which ephemerides loaded) and on which it also depends somehow must
be known when deserializing it again. Looking at the problem from a
pure technical point of view, serializing only the bits and bytes
the object is composed of may be sufficient, but imho it is also
very important to know exactly what the data is all about, so you
can use it correctly for later calculations or analysis.
We can serialize a CelestialBody, or an Orbit, but how can we
ensure, that the same environment at its creation time is present
at the time of deserialization? And more importantly, how can we
indicate that there is a mis-alignment to prevent improper use of
data results which are very difficult to track down?
We can't ensure that. However, I see serialization as a simple
mechanism that can be used for some purposes, with its advantages and
drawbacks and the user must know what to do. In many cases,
serialization/deserialization are used together in a known context
(for example to transfer data in distributed applications) and the
meta-data should of course be set up accordingly at both sides, either
because it is transmitted too or because the settings are similar (for
example external data files like JPL ephemerides and so on).
Maybe something like this should not be the goal of a library like
orekit, but then I would remove serialization support completely to
not give the users a wrong impression on the use of it (And I know
that I now sound very much like Gilles ;-).
I still think serialization for simple classes that are mainly data
container (orbits, PVCoordinates, attitude ...) are useful (and I know
that I now sound very much like Luc writing that ;-).
In fact, we even advertise in the javadoc of IntegratedEphemeris that
it is serializable, and this was done on purpose. The reason was that
the ephemeris could be created by one application and then be
transmitted for reuse by many other connected applications without a
need to recompute, thus saving computation power.
Imho, shifting away from serializable algorithms is a good idea. I
do not think there exists a use-case where distributed computing
can / shall be achieved by transmitting both function and data.
So everyone seem to be OK with that part. I see the consensus as : for
algorithm-type objects, we don't serialize.
You can still convince me about data-holding objects, but for now I
think we have not reached a consensus.
Perhaps Orekit could acheive the same effect as Java Serialization
by adding support for parsing and emitting standardized file
formats. For example, an Orbit could be persisted in a CCSDS Orbit
Parameter Message. This approach has the advantages that it is
release independent, human readable, developers can refer to a
standard to understand the context of the data, and object creation
always happens through a constructor. The downside is, of course,
the extra effort to write parsers and emitters, but this may be
comparable to the effort required to implement Serializeable
correctly. Orekit already has some support for this with
TLEs(read+write) and SP3(read) files.
This is an interesting point, and in fact support for CCSDS
recommandations is already registered as a desired feature in the
forge (see <https://www.orekit.org/forge/issues/13>). If someone wants
it and is ready to pay for it, we are ready to do it on request.
best regards,
Luc
Regards,
Evan
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.