inception icon indicating copy to clipboard operation
inception copied to clipboard

Access to a project being deleted should be blocked

Open reckart opened this issue 3 years ago • 1 comments

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.

Expected benefit Faster project deletion.

reckart avatar Mar 08 '22 09:03 reckart

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

reckart avatar Mar 08 '22 10:03 reckart