Hi Charitha/Rasika
On Tue, Jan 23, 2018 at 8:17 PM, Rasika Perera <rasi...@wso2.com> wrote: > Good catch Charitha! As you explained this code might raise unforeseen > issues. > > However; if we are bringing the update operation mapping before the FCM > notification; as per [1] status of the push notification will be marked as > *COMPLETED* even before executing the notification sending process. And > this will cause another issue of an inconsistent state. > > Most of the time, these notification providers involves calling external > 3rd party libraries(eg. MQTT, FCM...etc). Suppose there's a > RuntimeException thrown while sending the push notification. Notification > status still will be marked as COMPLETED and will not try ever again since > it is not tracked with the current try-catch block(it only catches > PushNotificationExecutionFailedException). > > Thus, If we are changing the order as suggested please consider adding a > Throwable catch block(since notificationStrategy.execute() calls 3rd party > or untrusted libraries); > > try { > operationMappingDAO.updateOperationMapping(operationId, enrolmentId, > org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.PushNotificationStatus.COMPLETED); > notificationStrategy.execute(new NotificationContext(deviceId, > operation)); > } catch (Throwable e) { > log.error("Error occurred while sending push notifications to " + > deviceId.getType() + " device carrying id '" + > deviceId + "'", e); > // Reschedule if push notification failed. > operationMappingDAO.updateOperationMapping(operationId, enrolmentId, > org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.PushNotificationStatus.SCHEDULED); > } > > +1 for this approach. > > [1] https://github.com/wso2/carbon-device-mgt/blob/ > e56fb5f4de5d8f08af879a39a412ff501cba35fc/components/device- > mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/ > wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java#L196 > > On Tue, Jan 23, 2018 at 7:16 PM, Charitha Goonetilleke <charit...@wso2.com > > wrote: > >> Hi All, >> >> I have implemented state life cycle to prevent concurrent API call from >> agent to pending operations endpoint. However issue is still appearing. I >> have tested the same scenario with Update 10 and was able to reproduce the >> issue with Update 10 pack also. >> >> However as I figured out, we are sending FCM notification before updating >> operation mapping table[1]. Due to that device received FCM notification in >> realtime as same as it is being added to the Operations DB in the server. >> So there is chance to a raise condition and as a result, we are observing >> above exception. So we might need to send FCM notification after updating >> Operation Mapping in order to prevent that. WDYT? >> >> [1] https://github.com/wso2/carbon-device-mgt/blob/master/co >> mponents/device-mgt/org.wso2.carbon.device.mgt.core/src/ >> main/java/org/wso2/carbon/device/mgt/core/operation/mgt/Oper >> ationManagerImpl.java#L195 >> >> Thanks & Regards, >> /charithag >> >> On Tue, Jan 23, 2018 at 2:34 PM, Charitha Goonetilleke < >> charit...@wso2.com> wrote: >> >>> Hi All, >>> >>> I was able to figure out the root cause for the issue. As Geeth and >>> Rasika pointed out this is happening due to concurrent insert and update >>> query executions. The root cause for this is calling pending operations >>> endpoint more than once from a single android device at a given time. Due >>> to that concurrent insert and update happen in the DB level. Ideally a >>> device should not call pending operations endpoint simultaneously. But as >>> device may receive multiple FCM notifications within fractions of seconds, >>> it is triggering pending operation calls per notification. >>> >>> So I'm now implementing a state machine to avoid that raise condition. >>> >>> Thanks & Regards, >>> /charithag >>> >>> On Tue, Jan 23, 2018 at 2:14 PM, Rasika Perera <rasi...@wso2.com> wrote: >>> >>>> Hi All, >>>> >>>> This error has raised since two threads trying to update the DB with >>>> following requirements; >>>> >>>> Thread #1 >>>> waiting to lock PUBLIC.*DM_ENROLMENT_OP_MAPPING* while >>>> locking PUBLIC.*DM_OPERATION* (exclusive), PUBLIC. >>>> *DM_COMMAND_OPERATION* (exclusive). >>>> >>>> Thread #2 >>>> waiting to lock PUBLIC.DM_OPERATION while >>>> locking PUBLIC.*DM_ENROLMENT_OP_MAPPING* (exclusive), PUBLIC. >>>> *DM_DEVICE_OPERATION_RESPONSE* (exclusive)."; >>>> >>>> I noticed we are already using ";LOCK_TIMEOUT=60000" (60sec) H2 DB >>>> parameter which would allow sometime to continue the thread and do the DB >>>> update. >>>> >>>> Hence, this might happen when you are holding the debug pointer in >>>> updateOperation() method or in a state where device responses burst occurs. >>>> However the latter case is very rare on other DBs(other than embedded H2). >>>> We can even minimize the chance for a such issue implementing a LOCK for >>>> calling updateOperation method(might affect the performance). WDYT? >>>> >>>> Best Regards, >>>> ~Rasika >>>> >>>> On Tue, Jan 23, 2018 at 12:39 PM, Charitha Goonetilleke < >>>> charit...@wso2.com> wrote: >>>> >>>>> Hi All, >>>>> >>>>> I have encountered following exception intermittently on IoTS Update >>>>> 11, when testing with Android device. >>>>> >>>>> [2018-01-23 12:19:51,077] [IoT-Core] ERROR - >>>>> {org.wso2.carbon.mdm.services.android.services.impl.DeviceManagementServiceImpl} >>>>> Issue in retrieving operation management service instance >>>>> org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException: >>>>> Error occurred while updating the operation: 90 status:COMPLETED >>>>> at org.wso2.carbon.device.mgt.core.operation.mgt.OperationManag >>>>> erImpl.updateOperation(OperationManagerImpl.java:551) >>>>> at org.wso2.carbon.device.mgt.core.service.DeviceManagementProv >>>>> iderServiceImpl.updateOperation(DeviceManagementProviderServ >>>>> iceImpl.java:1426) >>>>> at org.wso2.carbon.mdm.services.android.util.AndroidDeviceUtils >>>>> .updateOperation(AndroidDeviceUtils.java:211) >>>>> at org.wso2.carbon.mdm.services.android.services.impl.DeviceMan >>>>> agementServiceImpl.updateOperations(DeviceManagementServiceI >>>>> mpl.java:184) >>>>> at org.wso2.carbon.mdm.services.android.services.impl.DeviceMan >>>>> agementServiceImpl.getPendingOperations(DeviceManagementServ >>>>> iceImpl.java:139) >>>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>>>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce >>>>> ssorImpl.java:62) >>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe >>>>> thodAccessorImpl.java:43) >>>>> at java.lang.reflect.Method.invoke(Method.java:498) >>>>> at org.apache.cxf.service.invoker.AbstractInvoker.performInvoca >>>>> tion(AbstractInvoker.java:188) >>>>> at org.apache.cxf.service.invoker.AbstractInvoker.invoke(Abstra >>>>> ctInvoker.java:104) >>>>> at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:204) >>>>> at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:101) >>>>> at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(S >>>>> erviceInvokerInterceptor.java:58) >>>>> at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleM >>>>> essage(ServiceInvokerInterceptor.java:94) >>>>> at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(Phase >>>>> InterceptorChain.java:272) >>>>> at org.apache.cxf.transport.ChainInitiationObserver.onMessage(C >>>>> hainInitiationObserver.java:121) >>>>> at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke >>>>> (AbstractHTTPDestination.java:249) >>>>> at org.apache.cxf.transport.servlet.ServletController.invokeDes >>>>> tination(ServletController.java:248) >>>>> at org.apache.cxf.transport.servlet.ServletController.invoke(Se >>>>> rvletController.java:222) >>>>> at org.apache.cxf.transport.servlet.ServletController.invoke(Se >>>>> rvletController.java:153) >>>>> at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke( >>>>> CXFNonSpringServlet.java:171) >>>>> at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleR >>>>> equest(AbstractHTTPServlet.java:289) >>>>> at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPut(A >>>>> bstractHTTPServlet.java:226) >>>>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:653) >>>>> at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service >>>>> (AbstractHTTPServlet.java:265) >>>>> at org.apache.catalina.core.ApplicationFilterChain.internalDoFi >>>>> lter(ApplicationFilterChain.java:303) >>>>> at org.apache.catalina.core.ApplicationFilterChain.doFilter(App >>>>> licationFilterChain.java:208) >>>>> at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilte >>>>> r.java:52) >>>>> at org.apache.catalina.core.ApplicationFilterChain.internalDoFi >>>>> lter(ApplicationFilterChain.java:241) >>>>> at org.apache.catalina.core.ApplicationFilterChain.doFilter(App >>>>> licationFilterChain.java:208) >>>>> at org.wso2.carbon.mdm.services.android.util.ApiOriginFilter.do >>>>> Filter(ApiOriginFilter.java:33) >>>>> at org.apache.catalina.core.ApplicationFilterChain.internalDoFi >>>>> lter(ApplicationFilterChain.java:241) >>>>> at org.apache.catalina.core.ApplicationFilterChain.doFilter(App >>>>> licationFilterChain.java:208) >>>>> at org.apache.catalina.core.StandardWrapperValve.invoke(Standar >>>>> dWrapperValve.java:218) >>>>> at org.apache.catalina.core.StandardContextValve.invoke(Standar >>>>> dContextValve.java:110) >>>>> at org.apache.catalina.authenticator.AuthenticatorBase.invoke(A >>>>> uthenticatorBase.java:506) >>>>> at org.apache.catalina.core.StandardHostValve.invoke(StandardHo >>>>> stValve.java:169) >>>>> at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorRepo >>>>> rtValve.java:103) >>>>> at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInv >>>>> ocation(CompositeValve.java:99) >>>>> at org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve$1.invoke >>>>> (CarbonTomcatValve.java:47) >>>>> at org.wso2.carbon.webapp.mgt.TenantLazyLoaderValve.invoke(Tena >>>>> ntLazyLoaderValve.java:57) >>>>> at org.wso2.carbon.webapp.authenticator.framework.WebappAuthent >>>>> icationValve.processRequest(WebappAuthenticationValve.java:151) >>>>> at org.wso2.carbon.webapp.authenticator.framework.WebappAuthent >>>>> icationValve.invoke(WebappAuthenticationValve.java:69) >>>>> at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invok >>>>> eValves(TomcatValveContainer.java:47) >>>>> at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(Comp >>>>> ositeValve.java:62) >>>>> at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetection >>>>> Valve.invoke(CarbonStuckThreadDetectionValve.java:159) >>>>> at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogVa >>>>> lve.java:962) >>>>> at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve. >>>>> invoke(CarbonContextCreatorValve.java:57) >>>>> at org.apache.catalina.core.StandardEngineValve.invoke(Standard >>>>> EngineValve.java:116) >>>>> at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAd >>>>> apter.java:445) >>>>> at org.apache.coyote.http11.AbstractHttp11Processor.process(Abs >>>>> tractHttp11Processor.java:1115) >>>>> at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler >>>>> .process(AbstractProtocol.java:637) >>>>> at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun >>>>> (NioEndpoint.java:1770) >>>>> at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(N >>>>> ioEndpoint.java:1729) >>>>> at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPool >>>>> Executor.java:1142) >>>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoo >>>>> lExecutor.java:617) >>>>> at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.r >>>>> un(TaskThread.java:61) >>>>> at java.lang.Thread.run(Thread.java:745) >>>>> Caused by: org.wso2.carbon.device.mgt.cor >>>>> e.operation.mgt.dao.OperationManagementDAOException: Error occurred >>>>> while inserting operation response >>>>> at org.wso2.carbon.device.mgt.core.operation.mgt.dao.impl.Gener >>>>> icOperationDAOImpl.addOperationResponse(GenericOperationDAOI >>>>> mpl.java:213) >>>>> at org.wso2.carbon.device.mgt.core.operation.mgt.OperationManag >>>>> erImpl.updateOperation(OperationManagerImpl.java:544) >>>>> ... 58 more >>>>> Caused by: org.h2.jdbc.JdbcSQLException: Deadlock detected. The >>>>> current transaction was rolled back. Details: " >>>>> Session #49 (user: WSO2CARBON) on thread pool-54-thread-1 is waiting >>>>> to lock PUBLIC.DM_ENROLMENT_OP_MAPPING while locking PUBLIC.DM_OPERATION >>>>> (exclusive), PUBLIC.DM_COMMAND_OPERATION (exclusive). >>>>> Session #59 (user: WSO2CARBON) on thread http-nio-9443-exec-27 is >>>>> waiting to lock PUBLIC.DM_OPERATION while locking >>>>> PUBLIC.DM_ENROLMENT_OP_MAPPING (exclusive), >>>>> PUBLIC.DM_DEVICE_OPERATION_RESPONSE >>>>> (exclusive)."; SQL statement: >>>>> INSERT INTO DM_DEVICE_OPERATION_RESPONSE(OPERATION_ID, ENROLMENT_ID, >>>>> EN_OP_MAP_ID, OPERATION_RESPONSE, RECEIVED_TIMESTAMP) VALUES(?, ?, ?, ?, >>>>> ?) >>>>> [40001-175] >>>>> at org.h2.message.DbException.getJdbcSQLException(DbException.j >>>>> ava:332) >>>>> at org.h2.message.DbException.get(DbException.java:172) >>>>> at org.h2.message.DbException.get(DbException.java:149) >>>>> at org.h2.table.RegularTable.doLock(RegularTable.java:504) >>>>> at org.h2.table.RegularTable.lock(RegularTable.java:450) >>>>> at org.h2.constraint.ConstraintReferential.existsRow(Constraint >>>>> Referential.java:375) >>>>> at org.h2.constraint.ConstraintReferential.checkRowOwnTable(Con >>>>> straintReferential.java:367) >>>>> at org.h2.constraint.ConstraintReferential.checkRow(ConstraintR >>>>> eferential.java:310) >>>>> at org.h2.table.Table.fireConstraints(Table.java:894) >>>>> at org.h2.table.Table.fireAfterRow(Table.java:911) >>>>> at org.h2.command.dml.Insert.insertRows(Insert.java:162) >>>>> at org.h2.command.dml.Insert.update(Insert.java:115) >>>>> at org.h2.command.CommandContainer.update(CommandContainer.java:79) >>>>> at org.h2.command.Command.executeUpdate(Command.java:253) >>>>> at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(Jdbc >>>>> PreparedStatement.java:154) >>>>> at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPrepared >>>>> Statement.java:140) >>>>> at org.wso2.carbon.device.mgt.core.operation.mgt.dao.impl.Gener >>>>> icOperationDAOImpl.addOperationResponse(GenericOperationDAOI >>>>> mpl.java:211) >>>>> ... 59 more >>>>> >>>>> >>>>> Thanks & regards, >>>>> /charithag >>>>> -- >>>>> *Charitha Goonetilleke* >>>>> Senior Software Engineer >>>>> WSO2 Inc.; http://wso2.com >>>>> lean.enterprise.middleware >>>>> >>>>> mobile: +94 77 751 3669 <%2B94777513669> >>>>> Twitter:@CharithaWs <https://twitter.com/CharithaWs>, fb: charithag >>>>> <https://www.facebook.com/charithag>, linkedin: charithag >>>>> <http://www.linkedin.com/in/charithag> >>>>> >>>>> <http://wso2.com/signature> >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "WSO2 IoT Team Group" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to iot-group+unsubscr...@wso2.com. >>>>> For more options, visit https://groups.google.com/a/wso2.com/d/optout. >>>>> >>>> >>>> >>>> >>>> -- >>>> With Regards, >>>> >>>> *Rasika Perera* >>>> Senior Software Engineer >>>> LinkedIn: http://lk.linkedin.com/in/rasika90 >>>> >>>> <http://wso2.com/signature> >>>> >>>> WSO2 Inc. www.wso2.com >>>> lean.enterprise.middleware >>>> >>> >>> >>> >>> -- >>> *Charitha Goonetilleke* >>> Senior Software Engineer >>> WSO2 Inc.; http://wso2.com >>> lean.enterprise.middleware >>> >>> mobile: +94 77 751 3669 <%2B94777513669> >>> Twitter:@CharithaWs <https://twitter.com/CharithaWs>, fb: charithag >>> <https://www.facebook.com/charithag>, linkedin: charithag >>> <http://www.linkedin.com/in/charithag> >>> >>> <http://wso2.com/signature> >>> >> >> >> >> -- >> *Charitha Goonetilleke* >> Senior Software Engineer >> WSO2 Inc.; http://wso2.com >> lean.enterprise.middleware >> >> mobile: +94 77 751 3669 <%2B94777513669> >> Twitter:@CharithaWs <https://twitter.com/CharithaWs>, fb: charithag >> <https://www.facebook.com/charithag>, linkedin: charithag >> <http://www.linkedin.com/in/charithag> >> >> <http://wso2.com/signature> >> > > > > -- > With Regards, > > *Rasika Perera* > Senior Software Engineer > LinkedIn: http://lk.linkedin.com/in/rasika90 > > <http://wso2.com/signature> > > WSO2 Inc. www.wso2.com > lean.enterprise.middleware > -- *Geeth Munasinghe* *WSO2, Inc. http://wso2.com <http://wso2.com/> * *lean.enterprise.middleware.* email: ge...@wso2.com phone:(+94) 777911226 <http://wso2.com/signature>
_______________________________________________ Dev mailing list Dev@wso2.org http://wso2.org/cgi-bin/mailman/listinfo/dev