Standalone setup parsing threadsafety [message #1799992] |
Tue, 18 December 2018 11:41  |
Eclipse User |
|
|
|
I have a question regarding standalone setup and thread-safety of parsing.
Here's the code I use for parsing String input:
Injector injector = new MyDslStandaloneSetup().createInjectorAndDoEMFRegistration();
IResourceFactory resourceFactory = injector.getInstance(IResourceFactory.class);
Provider<XtextResourceSet> xtextResourceSetProvider = injector.getInstance(new Key<Provider<XtextResourceSet>>() {});
XtextResourceSet resourceSet = xtextResourceSetProvider.get();
Resource resource = resourceFactory.createResource(URI.createURI(UUID.randomUUID() + ".mydsl"));
resourceSet.getResources().add(resource);
resource.load(new StringInputStream(body), null);
final EObject astRoot = resource.getContents().isEmpty() ? null : resource.getContents().get(0);
Question is - what of this can be reused with regard to thread safety? Are IResourceFactory and Provider<XtextResourceSet> thread-safe?
I suppose they should be, but I'm not sure.
Also is XtextResourceSet thread safe? I have doubts about that one, but maybe someone has at least a general idea whether it should be thread safe or not.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Re: Standalone setup parsing threadsafety [message #1800124 is a reply to message #1800122] |
Thu, 20 December 2018 04:38   |
Eclipse User |
|
|
|
P.S. Oh yes, I see them now - there are some static fields used in MyDslStandaloneSetupGenerated generated by Xtext, which MyDslStandaloneSetup extends (and MyDslWebSetup extends MyDslStandaloneSetup):
- Resource.Factory.Registry.INSTANCE
- EPackage.Registry.INSTANCE
- IResourceServiceProvider.Registry.INSTANCE
- MyDslPackage.eINSTANCE
- XtextPackage.eINSTANCE
These store shared instances of IResourceFactory and IResourceServiceProvider
public void register(Injector injector) {
if (!EPackage.Registry.INSTANCE.containsKey("http://www.mvmn.x/mydsl")) {
EPackage.Registry.INSTANCE.put("http://www.mvmn.x/mydsl", MyDslPackage.eINSTANCE);
}
IResourceFactory resourceFactory = injector.getInstance(IResourceFactory.class);
IResourceServiceProvider serviceProvider = injector.getInstance(IResourceServiceProvider.class);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("mydsl", resourceFactory);
IResourceServiceProvider.Registry.INSTANCE.getExtensionToFactoryMap().put("mydsl", serviceProvider);
}
@Override
public Injector createInjectorAndDoEMFRegistration() {
// register default ePackages
if (!Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().containsKey("ecore"))
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
"ecore", new EcoreResourceFactoryImpl());
if (!Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().containsKey("xmi"))
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
"xmi", new XMIResourceFactoryImpl());
if (!Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().containsKey("xtextbin"))
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
"xtextbin", new BinaryGrammarResourceFactoryImpl());
if (!EPackage.Registry.INSTANCE.containsKey(XtextPackage.eNS_URI))
EPackage.Registry.INSTANCE.put(XtextPackage.eNS_URI, XtextPackage.eINSTANCE);
Injector injector = createInjector();
register(injector);
return injector;
}
public Injector createInjector() {
return Guice.createInjector(new MyDslRuntimeModule());
}
So whenever I create new instance of MyDslWebSetup or MyDslStandalone setup - I still get those instances shared, so I don't have threadsafety guarantees whatever I do.
Why does Xtext generate such a thing?
[Updated on: Thu, 20 December 2018 04:56] by Moderator
|
|
|
|
|
|
Re: Standalone setup parsing threadsafety [message #1800133 is a reply to message #1800130] |
Thu, 20 December 2018 05:40   |
Eclipse User |
|
|
|
Mykola Makhin wrote on Thu, 20 December 2018 05:07I conclude that Xtext web setup IS or at least MUST BE thread safe
HI
I'm not sure whether you are too naive of too optimistic.
Code is only threadsafe if it is designed, coded and tested to be threadsafe; possibly by running in a single thread sandbox. I very much doubt that XtextServlet fullfills any of the foregoing.
Providing non-trivial threadsafe functionality is very very hard, and almost certainly requires the designers to be motivated from the outset to use disciplined idioms universally, probably aided by autogeneration. Testing thread safety is close to impossible without a disciplined autogeneration that is provably rather than accidentally threadsafe.
Given that EMF itself is not thread safe, and that extended EMF, e.g. EMF + OCL delegates, is definitely not threadsafe, there is clearly no way that Xtext designers could be expected to make even the slightest effort to make Xtext fully threadsafe.
If you want to use Xtext in a threadsafe production, rather than research, context, you should instrument all Xtext's caches to confirm that no changes occur after you have done what you think is appropriate to warm them up. You might need to use Java reflection to discover all the caches by computation rather than by manual enumeration.
Regards
Ed Willink
|
|
|
Re: Standalone setup parsing threadsafety [message #1800136 is a reply to message #1800133] |
Thu, 20 December 2018 06:05   |
Eclipse User |
|
|
|
Ed Willink wrote on Thu, 20 December 2018 10:40Mykola Makhin wrote on Thu, 20 December 2018 05:07I conclude that Xtext web setup IS or at least MUST BE thread safe
HI
I'm not sure whether you are too naive of too optimistic.
I'm being realistic here. Xtext claims to have web integration, using XtextServlet. Servlets must be thread safe because they are used in multi-threaded environment (servlet container) where every HTTP request is processed in a separate thread. This is a definition of servlet.
Which of these facts do you think is false? Are you implying that Xtext developers lie when they say it has web integration since XtextServlet is flawed because it's not threadsafe?
XtextServlet can either be thread-safe, or not a properly written servlet (simply speaking, broken). It's either of the two, can't be both. If XtextServlet is not thread safe - it means XtextServlet is broken.
But so far I did not find it to be broken - it works perfectly fine for me (as long as I reuse an instance of Injector created by MyDslWebSetup.createInjectorAndDoEMFRegistration method but keep access to XtextResourceSet/Resource single-threaded/synchronized) - and it is being used by multiple threads by definition and in practice.
Quoting the servlet API javadoc:
https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServlet.html
Quote: Servlets typically run on multithreaded servers, so be aware that a servlet must handle concurrent requests and be careful to synchronize access to shared resources. Shared resources include in-memory data such as instance or class variables and external objects such as files, database connections, and network connections.
[Updated on: Thu, 20 December 2018 06:18] by Moderator
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.08396 seconds