Describe the refactoring action
Measures should be taken that access to a project that is in the process of being deleted is blocked. This should in particular avoid situations such as an already deleted index being "resurrected" by a user editing a document, but also other situations such as opening/editing documents in such a project or importing new documents etc. etc. - no actions at all should be permitted on a project that is in the process of being deleted - even if the deletion takes a longer time.
Currently, it appears that when deleting a project, the project documents are de-indexed one by one:
at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:361) ~[spring-context-5.3.15.jar!/:5.3.15]
at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:229) ~[spring-context-5.3.15.jar!/:5.3.15]
at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:166) ~[spring-context-5.3.15.jar!/:5.3.15]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) ~[spring-context-5.3.15.jar!/:5.3.15]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) ~[spring-context-5.3.15.jar!/:5.3.15]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) ~[spring-context-5.3.15.jar!/:5.3.15]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421) ~[spring-context-5.3.15.jar!/:5.3.15]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378) ~[spring-context-5.3.15.jar!/:5.3.15]
at de.tudarmstadt.ukp.clarin.webanno.api.dao.DocumentServiceImpl.removeSourceDocument(DocumentServiceImpl.java:590) ~[inception-api-dao-22.4.jar!/:?]
at de.tudarmstadt.ukp.clarin.webanno.api.dao.DocumentServiceImpl$$FastClassBySpringCGLIB$$7e8e7e07.invoke(<generated>) ~[inception-api-dao-22.4.jar!/:?]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.15.jar!/:5.3.15]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.15.jar!/:5.3.15]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:61) ~[spring-security-core-5.6.1.jar!/:5.6.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698) ~[spring-aop-5.3.15.jar!/:5.3.15]
at de.tudarmstadt.ukp.clarin.webanno.api.dao.DocumentServiceImpl$$EnhancerBySpringCGLIB$$7554350e.removeSourceDocument(<generated>) ~[inception-api-dao-22.4.jar!/:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at org.apache.wicket.proxy.jdk.JdkProxyFactory$JdkHandler.invoke(JdkProxyFactory.java:172) ~[wicket-ioc-9.7.0.jar!/:9.7.0]
at com.sun.proxy.$Proxy217.removeSourceDocument(Unknown Source) ~[?:?]
at de.tudarmstadt.ukp.clarin.webanno.ui.project.documents.DocumentListPanel.lambda$actionDelete$1148210f$1(DocumentListPanel.java:109) ~[inception-ui-project-22.4.jar!/:?]
Caused by: org.apache.lucene.store.LockObtainFailedException: Lock held by this virtual machine: /export/repository/project/29/indexMtas/write.lock
at org.apache.lucene.store.NativeFSLockFactory.obtainFSLock(NativeFSLockFactory.java:139) ~[lucene-core-7.7.3.jar!/:7.7.3 1a0d2a901dfec93676b0fe8be425101ceb754b85 - noble - 2020-04-21 10:31:55]
at org.apache.lucene.store.FSLockFactory.obtainLock(FSLockFactory.java:41) ~[lucene-core-7.7.3.jar!/:7.7.3 1a0d2a901dfec93676b0fe8be425101ceb754b85 - noble - 2020-04-21 10:31:55]
at org.apache.lucene.store.BaseDirectory.obtainLock(BaseDirectory.java:45) ~[lucene-core-7.7.3.jar!/:7.7.3 1a0d2a901dfec93676b0fe8be425101ceb754b85 - noble - 2020-04-21 10:31:55]
at org.apache.lucene.index.IndexWriter.<init>(IndexWriter.java:728) ~[lucene-core-7.7.3.jar!/:7.7.3 1a0d2a901dfec93676b0fe8be425101ceb754b85 - noble - 2020-04-21 10:31:55]
at de.tudarmstadt.ukp.inception.search.index.mtas.MtasDocumentIndex.getIndexWriter(MtasDocumentIndex.java:240) ~[inception-search-mtas-22.4.jar!/:?]
at de.tudarmstadt.ukp.inception.search.index.mtas.MtasDocumentIndex.deindexDocument(MtasDocumentIndex.java:1262) ~[inception-search-mtas-22.4.jar!/:?]
at de.tudarmstadt.ukp.inception.search.index.mtas.MtasDocumentIndex.deindexDocument(MtasDocumentIndex.java:1311) ~[inception-search-mtas-22.4.jar!/:?]
at de.tudarmstadt.ukp.inception.search.SearchServiceImpl.beforeDocumentRemove(SearchServiceImpl.java:342) ~[inception-search-core-22.4.jar!/:?]
at de.tudarmstadt.ukp.inception.search.SearchServiceImpl$$FastClassBySpringCGLIB$$d6146f50.invoke(<generated>) ~[inception-search-core-22.4.jar!/:?]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.15.jar!/:5.3.15]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.15.jar!/:5.3.15]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.15.jar!/:5.3.15]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698) ~[spring-aop-5.3.15.jar!/:5.3.15]
at de.tudarmstadt.ukp.inception.search.SearchServiceImpl$$EnhancerBySpringCGLIB$$c5f26f5f.beforeDocumentRemove(<generated>) ~[inception-search-core-22.4.jar!/:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:344) ~[spring-context-5.3.15.jar!/:5.3.15]
... 142 more
Since the index must be fully deleted as part of the project deletion, it would be sufficient to maybe discard and disable the index directly at the start of the project deletion.
Actually, the index is dropped directly at the start of the deletion:
trigger the deletion of the project
this causes the index to be discarded and to be unloaded in SearchServiceImpl.beforeProjectRemove(BeforeProjectRemovedEvent)
while the project deletion is still in progress, a user can perform some action that causes a SearchServiceImpl.indexDocument(AnnotationDocument, byte[]) to be called - which noticed that there isn't an index anymore and created a new one -- this is a situation which should be prevented
Describe the refactoring action Measures should be taken that access to a project that is in the process of being deleted is blocked. This should in particular avoid situations such as an already deleted index being "resurrected" by a user editing a document, but also other situations such as opening/editing documents in such a project or importing new documents etc. etc. - no actions at all should be permitted on a project that is in the process of being deleted - even if the deletion takes a longer time.
Currently, it appears that when deleting a project, the project documents are de-indexed one by one:
Since the index must be fully deleted as part of the project deletion, it would be sufficient to maybe discard and disable the index directly at the start of the project deletion.
Expected benefit Faster project deletion.