viatra / EMF-IncQuery

This repository is only kept for historic reasons. All development happens on eclipse.org
http://eclipse.org/viatra
13 stars 4 forks source link

introduce unmanaged engines and rederict matchers if their Rete network was wiped #258

Closed abelhegedus closed 12 years ago

abelhegedus commented 12 years ago

Short version: allow the creation of unmanaged IncQuery engines that are not handled by the EngineManager, thus allowing multiple Engines for the same Notifier. Engine wipe and dispose are only available for unmanaged engines. Furthermore, add indirection through the engine in matchers when accessing their Rete network so they can return proper results even if the engine was wiped.

In the current setup, IncQuery engines are instantiated through the EngineManager and the manager stores one engine for a given notifier (Resource, ResourceSet, EObject). Since it is possible to create matchers from patterns, the following problem has occurred twice in the last few days in completely different usecases:

  1. A pattern P with fully-qualified name FQN from the pattern model retrieved from the EIQ editor is used to create a matcher on resource set R.
  2. The EIQ file content changes, thus the pattern model is rebuilt, and the pattern with FQN is now P'.
  3. P' is used to create a matcher on R.
  4. IncQuery exception, since P and P' are not equal.

A possible workaround is to wipe the engine before creating a matcher for patterns of a new pattern model. However, if there are two objects A and B, who both use R and P, well-known serialization problem for operations appears:

a. A wipes the engine, loads P and uses the matcher Ma. b. B wipes the engine, loads P and uses the matcher Mb.

If a -> b, then Ma will give false results (if the input model changes). If b -> a, then Mb will give false results (if the input model changes).

The main problem is that anyone who has access to an engine can call wipe (and dispose), which in turn makes matchers created by others on the same engine unusable. Also, only one engine is allowed for a given notifier, since the constructor is hidden and invoked through the manager.

After some discussion with @bergmanngabor , we came up with the following ideas:

  1. Add a createUnmanagedEngine(Notifier) method to the EngineManager, which creates an IncQueryEngine without setting its manager field. Also, the manager won't include this engine in its map.
  2. Forbid the use of wipe and dispose on managed engines. The rationale behind this is to ensure that different users of the same managed engine don't interfere with each other. (this can manifest in a manager == null check)
  3. Matchers created for unmanaged engines should not fail completely when the engine is wiped. This can be solved by going through the engine to retrieve the Rete network in methods like getAllMatches and such, instead of using their own reference.
  4. Wipe and dispose may be allowed on managed engines as well, if we can come up with a nice mechanism for notifying users of the engine of this fact.
istvanrath commented 12 years ago

Decision: points 1,2,4: OK, 3: Optionally OK.

abelhegedus commented 12 years ago

Points 1 and 4 are done. Point 2 is currently handled by explicitly stating in the JavaDoc that wipe and dispose on managed engines should be done with care. After some discussion with @bergmanngabor, Point 3 will not be supported, as the cornercase where it is useful does not worth the effort required to solve it without breaking the existing API. Users with stored matcher objects should use wipe listeners.

Since the main "culprit" is the Query Explorer (calling both wipe and dispose on managed engines in it's original state), I have rewritten it to use unmanaged engines. It seems to work properly at first (wipe callbacks on derived features are not called).

I'm setting the issue to resolved. It can be closed if noone has objections or additional reuqests.