Re: Concurrent access to a shared (Ont)Model
Sorry, false alarm: this turned out to be a simpler case of Model modification during iteration, obscured by a recursive call. On Fri, Aug 26, 2016 at 8:04 PM, Martynas Jusevičiuswrote: > Hey Dave, > > another case of this came up. When calling imports.hasNext() on > > ExtendedIterator imports = ontology.listImports(); > > I consistently get ConcurrentModificationException: > > at > org.apache.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkCME(LPTopGoalIterator.java:248) > at > org.apache.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:222) > at > org.apache.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) > at > org.apache.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) > at > org.apache.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:55) > at > org.apache.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) > at > org.apache.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:55) > at org.apache.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:49) > at > org.apache.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) > at org.apache.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:49) > > Is there something special about listImports()? Is that considered a > WRITE operation? > > I am creating a new OntModel with each request to avoid concurrent > access, so I am quite sure (not 100% certain though) that nothing else > is modifying this OntModel at the same time. As I had understood, in > that case it should not be necessary to lock the model explicitly? > > I am attempting to implement polymorphism support, not sure if it > could be related. > > On Fri, Jul 22, 2016 at 9:24 AM, Dave Reynolds > wrote: >> On 21/07/16 22:26, Martynas Jusevičius wrote: >>> >>> Thanks Dave. Does the following code look reasonable? >>> >>> >>> OntModel ontModel = >>> OntDocumentManager.getInstance().getOntology(ontologyURI, >>> ontModelSpec); >>> ontModel.enterCriticalSection(Lock.READ); >>> try >>> { >>> OntModel clonedModel = >>> ModelFactory.createOntologyModel(ontModelSpec); >>> clonedModel.add(ontModel); >>> return clonedModel; >>> } >>> finally >>> { >>> ontModel.leaveCriticalSection(); >>> } >> >> >> Seems reasonable so long as all the code that uses ontModel is similarly >> wrapped in critical sections. >> >> Dave >> >> >>> On Wed, Jul 20, 2016 at 10:46 AM, Dave Reynolds >>> wrote: So that's the reasoner in which case you need to lock the OntModel. Dave On 19/07/16 17:04, Martynas Jusevičius wrote: > > > Hey Andy, > > I am not sure yet what is it that I need to lock - is it the OntModel, > or > the OntDocumentManager instance, or maybe both. > > But here are 2 actual exceptions: > > java.util.ConcurrentModificationException > at > > > com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkCME(LPTopGoalIterator.java:247) > at > > > com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:221) > at > > > com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) > at > > > com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) > at > > > com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) > at > > > com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) > at > > > com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) > at > com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) > at > > > com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) > at > com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) > at > > > com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) > at > > > com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) > at > > > com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) > at > > > com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) > at > > > com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) > at > > > com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) > at > > > org.graphity.client.filter.response.ConstructorBase.construct(ConstructorBase.java:130) > > > > > java.util.ConcurrentModificationException: Due to closed iterator
Re: Concurrent access to a shared (Ont)Model
Hey Dave, another case of this came up. When calling imports.hasNext() on ExtendedIterator imports = ontology.listImports(); I consistently get ConcurrentModificationException: at org.apache.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkCME(LPTopGoalIterator.java:248) at org.apache.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:222) at org.apache.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at org.apache.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at org.apache.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:55) at org.apache.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at org.apache.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:55) at org.apache.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:49) at org.apache.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at org.apache.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:49) Is there something special about listImports()? Is that considered a WRITE operation? I am creating a new OntModel with each request to avoid concurrent access, so I am quite sure (not 100% certain though) that nothing else is modifying this OntModel at the same time. As I had understood, in that case it should not be necessary to lock the model explicitly? I am attempting to implement polymorphism support, not sure if it could be related. On Fri, Jul 22, 2016 at 9:24 AM, Dave Reynoldswrote: > On 21/07/16 22:26, Martynas Jusevičius wrote: >> >> Thanks Dave. Does the following code look reasonable? >> >> >> OntModel ontModel = >> OntDocumentManager.getInstance().getOntology(ontologyURI, >> ontModelSpec); >> ontModel.enterCriticalSection(Lock.READ); >> try >> { >> OntModel clonedModel = >> ModelFactory.createOntologyModel(ontModelSpec); >> clonedModel.add(ontModel); >> return clonedModel; >> } >> finally >> { >> ontModel.leaveCriticalSection(); >> } > > > Seems reasonable so long as all the code that uses ontModel is similarly > wrapped in critical sections. > > Dave > > >> On Wed, Jul 20, 2016 at 10:46 AM, Dave Reynolds >> wrote: >>> >>> So that's the reasoner in which case you need to lock the OntModel. >>> >>> Dave >>> >>> >>> On 19/07/16 17:04, Martynas Jusevičius wrote: Hey Andy, I am not sure yet what is it that I need to lock - is it the OntModel, or the OntDocumentManager instance, or maybe both. But here are 2 actual exceptions: java.util.ConcurrentModificationException at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkCME(LPTopGoalIterator.java:247) at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:221) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at org.graphity.client.filter.response.ConstructorBase.construct(ConstructorBase.java:130) java.util.ConcurrentModificationException: Due to closed iterator com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkClosed(LPTopGoalIterator.java:256) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.moveForward(LPTopGoalIterator.java:95) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:222)
Re: Concurrent access to a shared (Ont)Model
Dave, I was doing OntModel ontModel = OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); ... OntModel clonedModel = ModelFactory.createOntologyModel(ontModelSpec); where ontModelSpec was new OntModelSpec(OntModelSpec.OWL_MEM) with GenericRuleReasoner set. I guess I do not need inference for the cloned Model if I can simply copy all the inferred statements, and the cloned Model is read-only. I changed the clonedModel spec to OntModelSpec.OWL_MEM, without the reasoner. The size() seems to match, as far as I observed. Is that what you suggested? The "explicit OntModelSpec" part was a bit unclear. On Sat, Jul 23, 2016 at 12:55 PM, Dave Reynoldswrote: > On 22/07/16 21:42, Martynas Jusevičius wrote: >> >> Is clonedModel.add(ontModel) the best way to clone a model though? >> Because after that ontModel.size() and clonedModel.size() seem to >> differ sometimes, e.g. 4723 vs 4729. > > > I expect you've got inference enabled on both ontModel and clonedModel. In > particular clonedModel looks like it has the default RDFS inference. > > So the copy is copying all the inference closure it can find but the > clonedModel inference is finding a little more. This is possible since the > rule-based OWL inference is correct but not complete - by materializing some > backward inferences you then make then available to forward inference again > and so open up some additional deductions. The chances are that these are > rather "uninteresting" extra inferences. > > I'd suggest having no inference for the clonedModel (explicit OntModelSpec). > If you need runtime inference for both then add just ontModel.getBaseModel() > to the clonedMOdel. > > Dave > > For the clonedModel > >> On Fri, Jul 22, 2016 at 9:24 AM, Dave Reynolds >> wrote: >>> >>> On 21/07/16 22:26, Martynas Jusevičius wrote: Thanks Dave. Does the following code look reasonable? OntModel ontModel = OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); ontModel.enterCriticalSection(Lock.READ); try { OntModel clonedModel = ModelFactory.createOntologyModel(ontModelSpec); clonedModel.add(ontModel); return clonedModel; } finally { ontModel.leaveCriticalSection(); } >>> >>> >>> >>> Seems reasonable so long as all the code that uses ontModel is similarly >>> wrapped in critical sections. >>> >>> Dave >>> >>> On Wed, Jul 20, 2016 at 10:46 AM, Dave Reynolds wrote: > > > So that's the reasoner in which case you need to lock the OntModel. > > Dave > > > On 19/07/16 17:04, Martynas Jusevičius wrote: >> >> >> >> Hey Andy, >> >> I am not sure yet what is it that I need to lock - is it the OntModel, >> or >> the OntDocumentManager instance, or maybe both. >> >> But here are 2 actual exceptions: >> >> java.util.ConcurrentModificationException >> at >> >> >> >> com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkCME(LPTopGoalIterator.java:247) >> at >> >> >> >> com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:221) >> at >> >> >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> >> >> com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) >> at >> >> >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> >> >> com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) >> at >> >> com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) >> at >> >> >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) >> at >> >> >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> >> >> com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) >> at >> >> >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> >> >> com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) >> at >> >> >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> >> >>
Re: Concurrent access to a shared (Ont)Model
On 22/07/16 21:42, Martynas Jusevičius wrote: Is clonedModel.add(ontModel) the best way to clone a model though? Because after that ontModel.size() and clonedModel.size() seem to differ sometimes, e.g. 4723 vs 4729. I expect you've got inference enabled on both ontModel and clonedModel. In particular clonedModel looks like it has the default RDFS inference. So the copy is copying all the inference closure it can find but the clonedModel inference is finding a little more. This is possible since the rule-based OWL inference is correct but not complete - by materializing some backward inferences you then make then available to forward inference again and so open up some additional deductions. The chances are that these are rather "uninteresting" extra inferences. I'd suggest having no inference for the clonedModel (explicit OntModelSpec). If you need runtime inference for both then add just ontModel.getBaseModel() to the clonedMOdel. Dave For the clonedModel On Fri, Jul 22, 2016 at 9:24 AM, Dave Reynoldswrote: On 21/07/16 22:26, Martynas Jusevičius wrote: Thanks Dave. Does the following code look reasonable? OntModel ontModel = OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); ontModel.enterCriticalSection(Lock.READ); try { OntModel clonedModel = ModelFactory.createOntologyModel(ontModelSpec); clonedModel.add(ontModel); return clonedModel; } finally { ontModel.leaveCriticalSection(); } Seems reasonable so long as all the code that uses ontModel is similarly wrapped in critical sections. Dave On Wed, Jul 20, 2016 at 10:46 AM, Dave Reynolds wrote: So that's the reasoner in which case you need to lock the OntModel. Dave On 19/07/16 17:04, Martynas Jusevičius wrote: Hey Andy, I am not sure yet what is it that I need to lock - is it the OntModel, or the OntDocumentManager instance, or maybe both. But here are 2 actual exceptions: java.util.ConcurrentModificationException at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkCME(LPTopGoalIterator.java:247) at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:221) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at org.graphity.client.filter.response.ConstructorBase.construct(ConstructorBase.java:130) java.util.ConcurrentModificationException: Due to closed iterator com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkClosed(LPTopGoalIterator.java:256) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.moveForward(LPTopGoalIterator.java:95) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:222) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:85) com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:74) com.hp.hpl.jena.xmloutput.impl.Basic.writeBody(Basic.java:48) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.writeXMLBody(BaseXMLWriter.java:492) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:464) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:450)
Re: Concurrent access to a shared (Ont)Model
Is clonedModel.add(ontModel) the best way to clone a model though? Because after that ontModel.size() and clonedModel.size() seem to differ sometimes, e.g. 4723 vs 4729. On Fri, Jul 22, 2016 at 9:24 AM, Dave Reynoldswrote: > On 21/07/16 22:26, Martynas Jusevičius wrote: >> >> Thanks Dave. Does the following code look reasonable? >> >> >> OntModel ontModel = >> OntDocumentManager.getInstance().getOntology(ontologyURI, >> ontModelSpec); >> ontModel.enterCriticalSection(Lock.READ); >> try >> { >> OntModel clonedModel = >> ModelFactory.createOntologyModel(ontModelSpec); >> clonedModel.add(ontModel); >> return clonedModel; >> } >> finally >> { >> ontModel.leaveCriticalSection(); >> } > > > Seems reasonable so long as all the code that uses ontModel is similarly > wrapped in critical sections. > > Dave > > >> On Wed, Jul 20, 2016 at 10:46 AM, Dave Reynolds >> wrote: >>> >>> So that's the reasoner in which case you need to lock the OntModel. >>> >>> Dave >>> >>> >>> On 19/07/16 17:04, Martynas Jusevičius wrote: Hey Andy, I am not sure yet what is it that I need to lock - is it the OntModel, or the OntDocumentManager instance, or maybe both. But here are 2 actual exceptions: java.util.ConcurrentModificationException at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkCME(LPTopGoalIterator.java:247) at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:221) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at org.graphity.client.filter.response.ConstructorBase.construct(ConstructorBase.java:130) java.util.ConcurrentModificationException: Due to closed iterator com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkClosed(LPTopGoalIterator.java:256) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.moveForward(LPTopGoalIterator.java:95) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:222) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:85) com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:74) com.hp.hpl.jena.xmloutput.impl.Basic.writeBody(Basic.java:48) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.writeXMLBody(BaseXMLWriter.java:492) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:464) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:450) com.hp.hpl.jena.rdf.model.impl.ModelCom.write(ModelCom.java:340) com.hp.hpl.jena.ontology.impl.OntModelImpl.writeAll(OntModelImpl.java:2650) On Tue, 19 Jul 2016 at 14:04, Andy Seaborne wrote: > On 17/07/16
Re: Concurrent access to a shared (Ont)Model
On 21/07/16 22:26, Martynas Jusevičius wrote: Thanks Dave. Does the following code look reasonable? OntModel ontModel = OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); ontModel.enterCriticalSection(Lock.READ); try { OntModel clonedModel = ModelFactory.createOntologyModel(ontModelSpec); clonedModel.add(ontModel); return clonedModel; } finally { ontModel.leaveCriticalSection(); } Seems reasonable so long as all the code that uses ontModel is similarly wrapped in critical sections. Dave On Wed, Jul 20, 2016 at 10:46 AM, Dave Reynoldswrote: So that's the reasoner in which case you need to lock the OntModel. Dave On 19/07/16 17:04, Martynas Jusevičius wrote: Hey Andy, I am not sure yet what is it that I need to lock - is it the OntModel, or the OntDocumentManager instance, or maybe both. But here are 2 actual exceptions: java.util.ConcurrentModificationException at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkCME(LPTopGoalIterator.java:247) at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:221) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at org.graphity.client.filter.response.ConstructorBase.construct(ConstructorBase.java:130) java.util.ConcurrentModificationException: Due to closed iterator com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkClosed(LPTopGoalIterator.java:256) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.moveForward(LPTopGoalIterator.java:95) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:222) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:85) com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:74) com.hp.hpl.jena.xmloutput.impl.Basic.writeBody(Basic.java:48) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.writeXMLBody(BaseXMLWriter.java:492) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:464) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:450) com.hp.hpl.jena.rdf.model.impl.ModelCom.write(ModelCom.java:340) com.hp.hpl.jena.ontology.impl.OntModelImpl.writeAll(OntModelImpl.java:2650) On Tue, 19 Jul 2016 at 14:04, Andy Seaborne wrote: On 17/07/16 13:54, Martynas Jusevičius wrote: But then again, I cannot lock what I don't have: locks work on models, and I only get OntModel instance when getOntology() is called. Maybe synchronized is the solution here? You can lock how you like - the Jena lock code is helper code, to promote proper critical sections and make app writers aware that concurrency matters. It is not fundamental in any way - it's normally a a java ReentrantReadWriteLock with some tracking code to catch programming errors. If you are observing actual exceptions, it would be good to get the traces. The caches are based on Guava's thread safe cache code although (legacy) the cache setter is outside the get-or-fill operation. From reading the code, it looks like the worse that can happen is to read a remote resource more than once. But it's possible I've missed what happening. As a general system point : notional read operations that internally cache
Re: Concurrent access to a shared (Ont)Model
Thanks Dave. Does the following code look reasonable? OntModel ontModel = OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); ontModel.enterCriticalSection(Lock.READ); try { OntModel clonedModel = ModelFactory.createOntologyModel(ontModelSpec); clonedModel.add(ontModel); return clonedModel; } finally { ontModel.leaveCriticalSection(); } On Wed, Jul 20, 2016 at 10:46 AM, Dave Reynoldswrote: > So that's the reasoner in which case you need to lock the OntModel. > > Dave > > > On 19/07/16 17:04, Martynas Jusevičius wrote: >> >> Hey Andy, >> >> I am not sure yet what is it that I need to lock - is it the OntModel, or >> the OntDocumentManager instance, or maybe both. >> >> But here are 2 actual exceptions: >> >> java.util.ConcurrentModificationException >> at >> >> com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkCME(LPTopGoalIterator.java:247) >> at >> >> com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:221) >> at >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) >> at >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) >> at >> com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) >> at >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) >> at >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) >> at >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) >> at >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> at >> >> com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) >> at >> >> org.graphity.client.filter.response.ConstructorBase.construct(ConstructorBase.java:130) >> >> >> >> >> java.util.ConcurrentModificationException: Due to closed iterator >> >> com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkClosed(LPTopGoalIterator.java:256) >> >> com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.moveForward(LPTopGoalIterator.java:95) >> >> com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:222) >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> >> com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> >> com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) >> com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) >> >> com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) >> com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:85) >> com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:74) >> com.hp.hpl.jena.xmloutput.impl.Basic.writeBody(Basic.java:48) >> >> com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.writeXMLBody(BaseXMLWriter.java:492) >> com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:464) >> com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:450) >> com.hp.hpl.jena.rdf.model.impl.ModelCom.write(ModelCom.java:340) >> >> com.hp.hpl.jena.ontology.impl.OntModelImpl.writeAll(OntModelImpl.java:2650) >> >> On Tue, 19 Jul 2016 at 14:04, Andy Seaborne wrote: >> >>> On 17/07/16 13:54, Martynas Jusevičius wrote: But then again, I cannot lock what I don't have: locks work on models, >>> >>> and I only get OntModel instance when getOntology() is called. Maybe synchronized is the solution here? >>> >>> >>> You can lock how you like - the Jena lock code is helper code, to >>> promote proper critical sections and make app writers aware that >>> concurrency matters. It is not fundamental in any way - it's normally a >>> a java ReentrantReadWriteLock with some tracking code to catch >>> programming errors. >>> >>> If you are observing actual exceptions, it would be good to get the >>> traces. The caches are based on Guava's thread safe cache code although >>> (legacy) the cache setter is outside the get-or-fill operation. From >>> reading the code, it looks like the worse that can happen is to
Re: Concurrent access to a shared (Ont)Model
So that's the reasoner in which case you need to lock the OntModel. Dave On 19/07/16 17:04, Martynas Jusevičius wrote: Hey Andy, I am not sure yet what is it that I need to lock - is it the OntModel, or the OntDocumentManager instance, or maybe both. But here are 2 actual exceptions: java.util.ConcurrentModificationException at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkCME(LPTopGoalIterator.java:247) at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:221) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at org.graphity.client.filter.response.ConstructorBase.construct(ConstructorBase.java:130) java.util.ConcurrentModificationException: Due to closed iterator com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkClosed(LPTopGoalIterator.java:256) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.moveForward(LPTopGoalIterator.java:95) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:222) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:85) com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:74) com.hp.hpl.jena.xmloutput.impl.Basic.writeBody(Basic.java:48) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.writeXMLBody(BaseXMLWriter.java:492) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:464) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:450) com.hp.hpl.jena.rdf.model.impl.ModelCom.write(ModelCom.java:340) com.hp.hpl.jena.ontology.impl.OntModelImpl.writeAll(OntModelImpl.java:2650) On Tue, 19 Jul 2016 at 14:04, Andy Seabornewrote: On 17/07/16 13:54, Martynas Jusevičius wrote: But then again, I cannot lock what I don't have: locks work on models, and I only get OntModel instance when getOntology() is called. Maybe synchronized is the solution here? You can lock how you like - the Jena lock code is helper code, to promote proper critical sections and make app writers aware that concurrency matters. It is not fundamental in any way - it's normally a a java ReentrantReadWriteLock with some tracking code to catch programming errors. If you are observing actual exceptions, it would be good to get the traces. The caches are based on Guava's thread safe cache code although (legacy) the cache setter is outside the get-or-fill operation. From reading the code, it looks like the worse that can happen is to read a remote resource more than once. But it's possible I've missed what happening. As a general system point : notional read operations that internally cache should make themselves multi-thread-read safe. Andy On Sun, 17 Jul 2016 at 15:32, Martynas Jusevičius wrote: Better: transactions (3.1.0) http://jena.staging.apache.org/documentation/txn/transactions.html We now have a fully
Re: Concurrent access to a shared (Ont)Model
Hey Andy, I am not sure yet what is it that I need to lock - is it the OntModel, or the OntDocumentManager instance, or maybe both. But here are 2 actual exceptions: java.util.ConcurrentModificationException at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkCME(LPTopGoalIterator.java:247) at com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:221) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) at com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) at org.graphity.client.filter.response.ConstructorBase.construct(ConstructorBase.java:130) java.util.ConcurrentModificationException: Due to closed iterator com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.checkClosed(LPTopGoalIterator.java:256) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.moveForward(LPTopGoalIterator.java:95) com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext(LPTopGoalIterator.java:222) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.util.iterator.FilterIterator.hasNext(FilterIterator.java:54) com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext(Map1Iterator.java:48) com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext(WrappedIterator.java:90) com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:85) com.hp.hpl.jena.xmloutput.impl.Basic.writeRDFStatements(Basic.java:74) com.hp.hpl.jena.xmloutput.impl.Basic.writeBody(Basic.java:48) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.writeXMLBody(BaseXMLWriter.java:492) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:464) com.hp.hpl.jena.xmloutput.impl.BaseXMLWriter.write(BaseXMLWriter.java:450) com.hp.hpl.jena.rdf.model.impl.ModelCom.write(ModelCom.java:340) com.hp.hpl.jena.ontology.impl.OntModelImpl.writeAll(OntModelImpl.java:2650) On Tue, 19 Jul 2016 at 14:04, Andy Seabornewrote: > On 17/07/16 13:54, Martynas Jusevičius wrote: > > But then again, I cannot lock what I don't have: locks work on models, > and > > I only get OntModel instance when getOntology() is called. > > > > Maybe synchronized is the solution here? > > You can lock how you like - the Jena lock code is helper code, to > promote proper critical sections and make app writers aware that > concurrency matters. It is not fundamental in any way - it's normally a > a java ReentrantReadWriteLock with some tracking code to catch > programming errors. > > If you are observing actual exceptions, it would be good to get the > traces. The caches are based on Guava's thread safe cache code although > (legacy) the cache setter is outside the get-or-fill operation. From > reading the code, it looks like the worse that can happen is to read a > remote resource more than once. But it's possible I've missed what > happening. > > As a general system point : notional read operations that internally > cache should make themselves multi-thread-read safe. > > Andy > > > > On Sun, 17 Jul 2016 at 15:32, Martynas Jusevičius > > > wrote: > > > >> Thanks Andy. > >> > >> All of our code except OntDocumentManager access uses imutable objects, > so > >> I hope to keep lock usage to an absolute minimum. Transactions look > like an > >> overkill at this point. > >> > >> So if getOntology() is a write operation, if I wrap only this piece of > >> code where it is called into a WRITE critical section, wouldn't that be > >> enough? > >> > >> I think the docs lack an explanation on which ops are read and which are > >> write. > >> > >> On Sun, 17 Jul 2016 at 12:22, Andy Seaborne wrote: > >> > >>> Better: transactions (3.1.0) > >>> > >>>
Re: Concurrent access to a shared (Ont)Model
On 17/07/16 13:54, Martynas Jusevičius wrote: But then again, I cannot lock what I don't have: locks work on models, and I only get OntModel instance when getOntology() is called. Maybe synchronized is the solution here? You can lock how you like - the Jena lock code is helper code, to promote proper critical sections and make app writers aware that concurrency matters. It is not fundamental in any way - it's normally a a java ReentrantReadWriteLock with some tracking code to catch programming errors. If you are observing actual exceptions, it would be good to get the traces. The caches are based on Guava's thread safe cache code although (legacy) the cache setter is outside the get-or-fill operation. From reading the code, it looks like the worse that can happen is to read a remote resource more than once. But it's possible I've missed what happening. As a general system point : notional read operations that internally cache should make themselves multi-thread-read safe. Andy On Sun, 17 Jul 2016 at 15:32, Martynas Jusevičiuswrote: Thanks Andy. All of our code except OntDocumentManager access uses imutable objects, so I hope to keep lock usage to an absolute minimum. Transactions look like an overkill at this point. So if getOntology() is a write operation, if I wrap only this piece of code where it is called into a WRITE critical section, wouldn't that be enough? I think the docs lack an explanation on which ops are read and which are write. On Sun, 17 Jul 2016 at 12:22, Andy Seaborne wrote: Better: transactions (3.1.0) http://jena.staging.apache.org/documentation/txn/transactions.html We now have a fully ACID transactional in-memory graph (TIM) as well as TDB. The "Txn" highlevel API is not in the released codebase. http://jena.staging.apache.org/documentation/txn/txn.html Planning now for transactions should make things a lot easier later. Andy On 16/07/16 16:03, Martynas Jusevičius wrote: On a second thought, since our code is only reading from the models, it is probably easier and safer just to clone the shared model into a per-request copy, and keep the code as it is. If the shared model is only ever read, you can share it. (getOntology isn't a read operation.) Is the following code the fastest way to do it? Is add() expensive? OntModel ontModel = OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); OntModel clonedModel = ModelFactory.createOntologyModel(ontModelSpec); clonedModel.add(ontModel); On Sat, Jul 16, 2016 at 3:47 PM, Martynas Jusevičius < marty...@graphity.org> wrote: Hey, in our webapp, all objects are created per-request, except ontologies stored in a shared OntDocumentManager, that are accessed like this: OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); This has caused some ConcurrentModificationExceptions. I have read the https://jena.apache.org/documentation/notes/concurrency-howto.html document, and wanted to check if I get this right. Basically, every operation and iterator on a shared OntModel has to be in a critical section? Even if it's indirect and called on an OntClass from the OntModel: OntModel ontModel = OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); ontModel.enterCriticalSection(Lock.READ); try { OntClass ontClass = ontModel.getOntClass("http://some/class;); NodeIterator it = ontClass.listPropertyValues(GC.supportedMode); try { while (it.next) ... } finally { it.close(); } } finally { model.leaveCriticalSection() ; } Is that correct? Martynas
Re: Concurrent access to a shared (Ont)Model
But then again, I cannot lock what I don't have: locks work on models, and I only get OntModel instance when getOntology() is called. Maybe synchronized is the solution here? On Sun, 17 Jul 2016 at 15:32, Martynas Jusevičiuswrote: > Thanks Andy. > > All of our code except OntDocumentManager access uses imutable objects, so > I hope to keep lock usage to an absolute minimum. Transactions look like an > overkill at this point. > > So if getOntology() is a write operation, if I wrap only this piece of > code where it is called into a WRITE critical section, wouldn't that be > enough? > > I think the docs lack an explanation on which ops are read and which are > write. > > On Sun, 17 Jul 2016 at 12:22, Andy Seaborne wrote: > >> Better: transactions (3.1.0) >> >> http://jena.staging.apache.org/documentation/txn/transactions.html >> >> We now have a fully ACID transactional in-memory graph (TIM) as well as >> TDB. >> >> The "Txn" highlevel API is not in the released codebase. >> >> http://jena.staging.apache.org/documentation/txn/txn.html >> >> Planning now for transactions should make things a lot easier later. >> >> Andy >> >> On 16/07/16 16:03, Martynas Jusevičius wrote: >> > On a second thought, since our code is only reading from the models, it >> is >> > probably easier and safer just to clone the shared model into a >> per-request >> > copy, and keep the code as it is. >> >> If the shared model is only ever read, you can share it. >> >> (getOntology isn't a read operation.) >> >> > >> > Is the following code the fastest way to do it? Is add() expensive? >> > >> > >> > OntModel ontModel = >> > OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); >> > OntModel clonedModel = ModelFactory.createOntologyModel(ontModelSpec); >> > clonedModel.add(ontModel); >> > >> > >> > On Sat, Jul 16, 2016 at 3:47 PM, Martynas Jusevičius < >> marty...@graphity.org> >> > wrote: >> >> Hey, >> >> >> >> in our webapp, all objects are created per-request, except ontologies >> >> stored in a shared OntDocumentManager, that are accessed like this: >> >> >> >>OntDocumentManager.getInstance().getOntology(ontologyURI, >> ontModelSpec); >> >> >> >> This has caused some ConcurrentModificationExceptions. >> >> I have read the >> >> https://jena.apache.org/documentation/notes/concurrency-howto.html >> >> document, and wanted to check if I get this right. >> >> >> >> Basically, every operation and iterator on a shared OntModel has to be >> >> in a critical section? Even if it's indirect and called on an OntClass >> >> from the OntModel: >> >> >> >>OntModel ontModel = >> >> OntDocumentManager.getInstance().getOntology(ontologyURI, >> >> ontModelSpec); >> >>ontModel.enterCriticalSection(Lock.READ); >> >>try >> >>{ >> >> OntClass ontClass = ontModel.getOntClass("http://some/class;); >> >> NodeIterator it = ontClass.listPropertyValues(GC.supportedMode); >> >> try >> >> { >> >>while (it.next) >> >> ... >> >> } >> >> finally >> >> { >> >>it.close(); >> >> } >> >>} >> >>finally >> >>{ >> >> model.leaveCriticalSection() ; >> >>} >> >> >> >> Is that correct? >> >> >> >> Martynas >> > >> >>
Re: Concurrent access to a shared (Ont)Model
As I read the code, getOntology is a write operation just when it doesn't retrieve a pre-existing (cached) OntModel and must build a new one. If you can be sure that you have always beforehand written the OntModel you are retrieving into the OntDocumentManager using addModel, then I don't think getOntology will do any writing. On a side note, the locking in the current TIM implementation is pretty minimal and concerned almost entirely with commits. The use of persistent data structures means there are not granular locks inside the data structures, just a few dataset-wide locks that come into play briefly to begin and finish transactions cleanly. I don't think there is any possibility of long-running contention except for multiple threads trying to start WRITE transactions at the same time. (TIM is multiple-reader-and-single-writer.) --- A. Soroka The University of Virginia Library > On Jul 17, 2016, at 8:32 AM, Martynas Jusevičius> wrote: > > Thanks Andy. > > All of our code except OntDocumentManager access uses imutable objects, so > I hope to keep lock usage to an absolute minimum. Transactions look like an > overkill at this point. > > So if getOntology() is a write operation, if I wrap only this piece of code > where it is called into a WRITE critical section, wouldn't that be enough? > > I think the docs lack an explanation on which ops are read and which are > write. > > On Sun, 17 Jul 2016 at 12:22, Andy Seaborne wrote: > >> Better: transactions (3.1.0) >> >> http://jena.staging.apache.org/documentation/txn/transactions.html >> >> We now have a fully ACID transactional in-memory graph (TIM) as well as >> TDB. >> >> The "Txn" highlevel API is not in the released codebase. >> >> http://jena.staging.apache.org/documentation/txn/txn.html >> >> Planning now for transactions should make things a lot easier later. >> >>Andy >> >> On 16/07/16 16:03, Martynas Jusevičius wrote: >>> On a second thought, since our code is only reading from the models, it >> is >>> probably easier and safer just to clone the shared model into a >> per-request >>> copy, and keep the code as it is. >> >> If the shared model is only ever read, you can share it. >> >> (getOntology isn't a read operation.) >> >>> >>> Is the following code the fastest way to do it? Is add() expensive? >>> >>> >>> OntModel ontModel = >>> OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); >>> OntModel clonedModel = ModelFactory.createOntologyModel(ontModelSpec); >>> clonedModel.add(ontModel); >>> >>> >>> On Sat, Jul 16, 2016 at 3:47 PM, Martynas Jusevičius < >> marty...@graphity.org> >>> wrote: Hey, in our webapp, all objects are created per-request, except ontologies stored in a shared OntDocumentManager, that are accessed like this: OntDocumentManager.getInstance().getOntology(ontologyURI, >> ontModelSpec); This has caused some ConcurrentModificationExceptions. I have read the https://jena.apache.org/documentation/notes/concurrency-howto.html document, and wanted to check if I get this right. Basically, every operation and iterator on a shared OntModel has to be in a critical section? Even if it's indirect and called on an OntClass from the OntModel: OntModel ontModel = OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); ontModel.enterCriticalSection(Lock.READ); try { OntClass ontClass = ontModel.getOntClass("http://some/class;); NodeIterator it = ontClass.listPropertyValues(GC.supportedMode); try { while (it.next) ... } finally { it.close(); } } finally { model.leaveCriticalSection() ; } Is that correct? Martynas >>> >> >>
Re: Concurrent access to a shared (Ont)Model
Thanks Andy. All of our code except OntDocumentManager access uses imutable objects, so I hope to keep lock usage to an absolute minimum. Transactions look like an overkill at this point. So if getOntology() is a write operation, if I wrap only this piece of code where it is called into a WRITE critical section, wouldn't that be enough? I think the docs lack an explanation on which ops are read and which are write. On Sun, 17 Jul 2016 at 12:22, Andy Seabornewrote: > Better: transactions (3.1.0) > > http://jena.staging.apache.org/documentation/txn/transactions.html > > We now have a fully ACID transactional in-memory graph (TIM) as well as > TDB. > > The "Txn" highlevel API is not in the released codebase. > > http://jena.staging.apache.org/documentation/txn/txn.html > > Planning now for transactions should make things a lot easier later. > > Andy > > On 16/07/16 16:03, Martynas Jusevičius wrote: > > On a second thought, since our code is only reading from the models, it > is > > probably easier and safer just to clone the shared model into a > per-request > > copy, and keep the code as it is. > > If the shared model is only ever read, you can share it. > > (getOntology isn't a read operation.) > > > > > Is the following code the fastest way to do it? Is add() expensive? > > > > > > OntModel ontModel = > > OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); > > OntModel clonedModel = ModelFactory.createOntologyModel(ontModelSpec); > > clonedModel.add(ontModel); > > > > > > On Sat, Jul 16, 2016 at 3:47 PM, Martynas Jusevičius < > marty...@graphity.org> > > wrote: > >> Hey, > >> > >> in our webapp, all objects are created per-request, except ontologies > >> stored in a shared OntDocumentManager, that are accessed like this: > >> > >>OntDocumentManager.getInstance().getOntology(ontologyURI, > ontModelSpec); > >> > >> This has caused some ConcurrentModificationExceptions. > >> I have read the > >> https://jena.apache.org/documentation/notes/concurrency-howto.html > >> document, and wanted to check if I get this right. > >> > >> Basically, every operation and iterator on a shared OntModel has to be > >> in a critical section? Even if it's indirect and called on an OntClass > >> from the OntModel: > >> > >>OntModel ontModel = > >> OntDocumentManager.getInstance().getOntology(ontologyURI, > >> ontModelSpec); > >>ontModel.enterCriticalSection(Lock.READ); > >>try > >>{ > >> OntClass ontClass = ontModel.getOntClass("http://some/class;); > >> NodeIterator it = ontClass.listPropertyValues(GC.supportedMode); > >> try > >> { > >>while (it.next) > >> ... > >> } > >> finally > >> { > >>it.close(); > >> } > >>} > >>finally > >>{ > >> model.leaveCriticalSection() ; > >>} > >> > >> Is that correct? > >> > >> Martynas > > > >
Re: Concurrent access to a shared (Ont)Model
From my reading of the code, you will want explicitly add Models from a TIM dataset to the OntDocumentManager instance. In other words, don't use getOntology with having added the Model yourself, or the OntDocumentManager instance will create a Model outside the TIM dataset to give you. But I wouldn't pretend to be very familiar with the ontology side of things. --- A. Soroka The University of Virginia Library > On Jul 17, 2016, at 5:22 AM, Andy Seabornewrote: > > Better: transactions (3.1.0) > > http://jena.staging.apache.org/documentation/txn/transactions.html > > We now have a fully ACID transactional in-memory graph (TIM) as well as TDB. > > The "Txn" highlevel API is not in the released codebase. > > http://jena.staging.apache.org/documentation/txn/txn.html > > Planning now for transactions should make things a lot easier later. > > Andy > > On 16/07/16 16:03, Martynas Jusevičius wrote: >> On a second thought, since our code is only reading from the models, it is >> probably easier and safer just to clone the shared model into a per-request >> copy, and keep the code as it is. > > If the shared model is only ever read, you can share it. > > (getOntology isn't a read operation.) > >> >> Is the following code the fastest way to do it? Is add() expensive? >> >> >> OntModel ontModel = >> OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); >> OntModel clonedModel = ModelFactory.createOntologyModel(ontModelSpec); >> clonedModel.add(ontModel); >> >> >> On Sat, Jul 16, 2016 at 3:47 PM, Martynas Jusevičius >> wrote: >>> Hey, >>> >>> in our webapp, all objects are created per-request, except ontologies >>> stored in a shared OntDocumentManager, that are accessed like this: >>> >>> OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); >>> >>> This has caused some ConcurrentModificationExceptions. >>> I have read the >>> https://jena.apache.org/documentation/notes/concurrency-howto.html >>> document, and wanted to check if I get this right. >>> >>> Basically, every operation and iterator on a shared OntModel has to be >>> in a critical section? Even if it's indirect and called on an OntClass >>> from the OntModel: >>> >>> OntModel ontModel = >>> OntDocumentManager.getInstance().getOntology(ontologyURI, >>> ontModelSpec); >>> ontModel.enterCriticalSection(Lock.READ); >>> try >>> { >>> OntClass ontClass = ontModel.getOntClass("http://some/class;); >>> NodeIterator it = ontClass.listPropertyValues(GC.supportedMode); >>> try >>> { >>> while (it.next) >>> ... >>> } >>> finally >>> { >>> it.close(); >>> } >>> } >>> finally >>> { >>> model.leaveCriticalSection() ; >>> } >>> >>> Is that correct? >>> >>> Martynas >> >
Re: Concurrent access to a shared (Ont)Model
On a second thought, since our code is only reading from the models, it is probably easier and safer just to clone the shared model into a per-request copy, and keep the code as it is. Is the following code the fastest way to do it? Is add() expensive? OntModel ontModel = OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); OntModel clonedModel = ModelFactory.createOntologyModel(ontModelSpec); clonedModel.add(ontModel); On Sat, Jul 16, 2016 at 3:47 PM, Martynas Jusevičiuswrote: > Hey, > > in our webapp, all objects are created per-request, except ontologies > stored in a shared OntDocumentManager, that are accessed like this: > > OntDocumentManager.getInstance().getOntology(ontologyURI, ontModelSpec); > > This has caused some ConcurrentModificationExceptions. I have read the > https://jena.apache.org/documentation/notes/concurrency-howto.html > document, and wanted to check if I get this right. > > Basically, every operation and iterator on a shared OntModel has to be > in a critical section? Even if it's indirect and called on an OntClass > from the OntModel: > > OntModel ontModel = > OntDocumentManager.getInstance().getOntology(ontologyURI, > ontModelSpec); > ontModel.enterCriticalSection(Lock.READ); > try > { > OntClass ontClass = ontModel.getOntClass("http://some/class;); > NodeIterator it = ontClass.listPropertyValues(GC.supportedMode); > try > { > while (it.next) > ... > } > finally > { > it.close(); > } > } > finally > { > model.leaveCriticalSection() ; > } > > Is that correct? > > Martynas