On 05/06/2019 20:42, Amit Kumar wrote:
Hi Andy, Thanks for your reply. I tried your 2nd Option. The StoreConnection.release(location) option didn't seem to work. I'm assuming the location should point to the main TopLevel Directory /etc/fuseki/databases/201906031724/ ├── Data-0001 │ ├── GOSP.bpt │ ├── GOSP.dat | | ... │ └── tdb.lock └── tdb.lock I gave "/etc/fuseki/databases/201906031724" as location input
Checking the code, I see that for StoreConnection, it'll be /etc/fuseki/databases/201906031724/Data-0001 (StoreConnection in TDB2 manages the the current dataset; TDBInternal.expel understands switchable datasets - the level up at /etc/fuseki/databases/201906031724/.
Too much TDB1 thinking!
private boolean postProcessingWebServer(String path) { Location location = Location.create(path); String lockFilename = location.getPath(Names.TDB_LOCK_FILE); LOGGER.info("location {} is presence in StoreConnection.cache is {}", lockFilename, StoreConnection.isSetup(location)); StoreConnection.release(location); return ExecUtil.restartJetty(); } INFO location /etc/fuseki/databases/201906031724/tdb.lock is presence in StoreConnection.cache is false This option failed with the same original error. The storeConnection has a cache, and this location was not in that cache(). ============= So next I tried the following option private boolean postProcessingWebServer(String path) { Location location = Location.create(path); String lockFilename = location.getPath(Names.TDB_LOCK_FILE); LOGGER.info("location of the lock file is {}", lockFilename); StoreConnection storeConnection = StoreConnection.connectCreate(location); storeConnection.getLock().unlock(); return ExecUtil.restartJetty(); } This time I got the following error org.apache.jena.dboe.base.file.AlreadyLocked: Failed to get a lock: file='/etc/fuseki/databases/201906031727/tdb.lock': Lock already held at org.apache.jena.dboe.base.file.ProcessFileLock.lockOperation(ProcessFileLock.java:187) at org.apache.jena.dboe.base.file.ProcessFileLock.lockEx(ProcessFileLock.java:125) at org.apache.jena.tdb2.sys.StoreConnection.make(StoreConnection.java:87) at org.apache.jena.tdb2.sys.StoreConnection.connectCreate(StoreConnection.java:61) at org.apache.jena.tdb2.sys.StoreConnection.connectCreate(StoreConnection.java:52) ======== Then I tried to use the ProcessFileLock directly private boolean postProcessingWebServer(String path) { Location location = Location.create(path); String lockFilename = location.getPath(Names.TDB_LOCK_FILE); ProcessFileLock fileLock = ProcessFileLock.create(lockFilename); LOGGER.info("Lock exists for {} is {}", lockFilename, fileLock.isLockedHere()); fileLock.unlock(); return ExecUtil.restartJetty(); } INFO Lock exists for /etc/fuseki/databases/201906031755/tdb.lock is true Caused by: org.apache.jena.dboe.DBOpEnvException: Failed to get a lock: file='/etc/fuseki/databases/201906031755/Data-0001/tdb.lock': held by process 8211 at org.apache.jena.dboe.base.file.ProcessFileLock.lockOperation(ProcessFileLock.java:199) at org.apache.jena.dboe.base.file.ProcessFileLock.lockEx(ProcessFileLock.java:125) at org.apache.jena.tdb2.sys.StoreConnection.make(StoreConnection.java:87) at org.apache.jena.tdb2.sys.StoreConnection.connectCreate(StoreConnection.java:61) at org.apache.jena.tdb2.sys.DatabaseOps.createSwitchable(DatabaseOps.java:97) at org.apache.jena.tdb2.sys.DatabaseOps.create(DatabaseOps.java:78) at org.apache.jena.tdb2.sys.DatabaseConnection.buildForCache(DatabaseConnection.java:90) at org.apache.jena.tdb2.sys.DatabaseConnection.lambda$make$0(DatabaseConnection.java:76) at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) at org.apache.jena.tdb2.sys.DatabaseConnection.make(DatabaseConnection.java:76) at org.apache.jena.tdb2.sys.DatabaseConnection.connectCreate(DatabaseConnection.java:61) at org.apache.jena.tdb2.sys.DatabaseConnection.connectCreate(DatabaseConnection.java:52) This time the error was for the lock file which is inside the Data-0001 folder instead. ===== When I tried using the unlock on both the lock file explicitly, it worked. I also tried the TDBInternal.expel(dataset) and it worked private boolean postProcessingWebServer(String path) { Location location = Location.create(path); DatabaseConnection databaseConnection = DatabaseConnection.connectCreate(location); TDBInternal.expel(databaseConnection.getDatasetGraph()); return ExecUtil.restartJetty(); } I'm going ahead with the TDBInternal.expel option for now. Regards Amit On Sat, Jun 1, 2019 at 5:59 AM Andy Seaborne <[email protected]> wrote:Hi Amit, You are correct - when used in a JVM, the dataset remains manged by the JVM after loading. This is intentional - the app may want to use the dataset some more in Java code. You can: 1/ Fork the process as a separate OS process using java.util.ProcessBuilder 2/ Force it out of the running JVM with TDBInternal.expel(dataset) or StoreConenction.release(location) 3/ Work with the dataset in Fuseki - you can POST data to it 4/ Not use a war file but use Fuseki main, and run your program and Fuseki in the same JVM. Symbolic links make no difference - they are only involved in file system path naming. Once opened, the OS pathname isn't involved. Andy On 31/05/2019 21:23, Amit Kumar wrote:Hi, I'm having issue an issue with using Fuseki as a war file inside jetty.Wehave a java application which looks for new data and loads it ontofuseki.When it is doing it for the first time, it has to create a new index, sowecall the tdb2.tdbloader class directly with appropriate parameters. Hereisthe relevant code snippet import tdb2.tdbloader; ... public static List<String> TDBLoaderParams = Arrays.asList("-q","--loader", "parallel", "--loc"); ... List<String> tdbParams = new ArrayList<>(TDBLoaderParams); tdbParams.add(dstPath); tdbParams.addAll(srcPaths); try { ... tdbloader.main(tdbParams.toArray(new String[tdbParams.size()])); } ... ...This works as expected and create a new index at the desired location.Now,the problem is the same java process has to apply other feeds onto thesamegraph, so we move the softlink pointing to the fuseki database andexecutea jetty restart command by calling a shell action using JavaProcessBuilderprocess. The jetty though fails to restart with the following error:org.apache.jena.assembler.exceptions.AssemblerException: caught: Failedtoget a lock: file='/home/amit/fuseki/databases/201905302214/tdb.lock': held by process 35918 atorg.apache.jena.assembler.assemblers.AssemblerGroup$PlainAssemblerGroup.openBySpecificType(AssemblerGroup.java:165)atorg.apache.jena.assembler.assemblers.AssemblerGroup$PlainAssemblerGroup.open(AssemblerGroup.java:144)atorg.apache.jena.assembler.assemblers.AssemblerGroup$ExpandingAssemblerGroup.open(AssemblerGroup.java:93)atorg.apache.jena.assembler.assemblers.AssemblerBase.open(AssemblerBase.java:39)atorg.apache.jena.assembler.assemblers.AssemblerBase.open(AssemblerBase.java:35)atorg.apache.jena.fuseki.build.FusekiConfig.getDataset(FusekiConfig.java:353)atorg.apache.jena.fuseki.build.FusekiConfig.buildDataService(FusekiConfig.java:303)atorg.apache.jena.fuseki.build.FusekiConfig.buildDataAccessPoint(FusekiConfig.java:292)atorg.apache.jena.fuseki.build.FusekiConfig.readConfiguration(FusekiConfig.java:275)atorg.apache.jena.fuseki.build.FusekiConfig.readConfigurationDirectory(FusekiConfig.java:254)... ... Caused by: org.apache.jena.dboe.DBOpEnvException: Failed to getalock: file='/home/amit/fuseki/databases/201905302214/tdb.lock': held by process 35918 atorg.apache.jena.dboe.base.file.ProcessFileLock.lockOperation(ProcessFileLock.java:199)atorg.apache.jena.dboe.base.file.ProcessFileLock.lockEx(ProcessFileLock.java:125)atorg.apache.jena.tdb2.sys.DatabaseConnection.buildForCache(DatabaseConnection.java:88)atorg.apache.jena.tdb2.sys.DatabaseConnection.lambda$make$0(DatabaseConnection.java:76)atjava.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)So the Jetty Server fails to restart while the jvm that created the index is still active, even though it has completed the index building part. It restarts fine once the loader JVM dies. It looks like the parallelloaderclass is not releasing the lock() properly. FYI, I'm using 3.11 Jena From apache jena githubhttps://github.com/apache/jena/blob/66d14eda44dd0f37a9df31ed27c55c26600ff5f8/jena-db/jena-dboe-base/src/main/java/org/apache/jena/dboe/base/file/ProcessFileLock.java#L184-L218Regards Amit Kumar
