From dev-return-6294-archive-asf-public=cust-asf.ponee.io@servicecomb.apache.org Tue Jul 30 13:33:46 2019 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with SMTP id E7520180607 for ; Tue, 30 Jul 2019 15:33:45 +0200 (CEST) Received: (qmail 36359 invoked by uid 500); 30 Jul 2019 13:33:45 -0000 Mailing-List: contact dev-help@servicecomb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@servicecomb.apache.org Delivered-To: mailing list dev@servicecomb.apache.org Received: (qmail 36347 invoked by uid 99); 30 Jul 2019 13:33:45 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 30 Jul 2019 13:33:45 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id 87A58C2D6C for ; Tue, 30 Jul 2019 13:33:44 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 0.012 X-Spam-Level: X-Spam-Status: No, score=0.012 tagged_above=-999 required=6.31 tests=[RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, T_SPF_PERMERROR=0.01, URIBL_BLOCKED=0.001] autolearn=disabled Received: from mx1-ec2-va.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id qNhCbIXzs1vk for ; Tue, 30 Jul 2019 13:33:36 +0000 (UTC) Received-SPF: Permerror (mailfrom) identity=mailfrom; client-ip=59.111.176.17; helo=m17617.mail.qiye.163.com; envelope-from=zhang_lei@boco.com.cn; receiver= Received: from m17617.mail.qiye.163.com (m17617.mail.qiye.163.com [59.111.176.17]) by mx1-ec2-va.apache.org (ASF Mail Server at mx1-ec2-va.apache.org) with ESMTP id C50F5BC7F2 for ; Tue, 30 Jul 2019 13:33:32 +0000 (UTC) Received: from 10.0.0.19 (unknown [61.51.208.39]) by m17617.mail.qiye.163.com (Hmail) with ESMTPA id 8C3E02613D5 for ; Tue, 30 Jul 2019 21:33:20 +0800 (CST) From: Zhang Lei Content-Type: text/plain; charset=gb2312 Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 12.2 \(3445.102.3\)) Subject: Re: [DISCUSSION] Async support for Saga Date: Tue, 30 Jul 2019 21:33:19 +0800 References: To: dev@servicecomb.apache.org In-Reply-To: Message-Id: X-Mailer: Apple Mail (2.3445.102.3) X-HM-Spam-Status: e1kfGhgUHx5ZQUtXWQgYFAkeWUFZSVVJTk9LS0tKQ01CSUtKTFlXWShZQU hPN1dZLVlBSVdZCQ4XHghZQVk1NCk2OjckKS43PlkG X-HM-Sender-Digest: e1kMHhlZQR0aFwgeV1kSHx4VD1lBWUc6NFE6DQw*ODlKHlEVTU8SQhU0 NxBPFDpVSlVKTk1PT0JITUtPSklOVTMWGhIXVQETGhUcJBceEjsZFBgUVRgUFlUYFUVZV1kSC1lB WU1KVU5KVUlLQ1VIQllXWQgBWUFCTU9INwY+ X-HM-Tid: 0a6c4315d7639375kuws8c3e02613d5 Hi, Willem Do you mean by sending a TxAsyncStartEvent to Alpha before executing the = asynchronous method? Conversation: Omega: Hi, Alpha an asynchronous method is about to start, please wait = until you received sub-transaction events Alpha: Ok, I will wait until I receive a TxStartedEvent and a = TxEndedEvent or a TxAbortedEvent before ending the transaction. Lei Zhang > =D4=DA 2019=C4=EA7=D4=C230=C8=D5=A3=AC=C9=CF=CE=E78:49=A3=ACWillem = Jiang =D0=B4=B5=C0=A3=BA >=20 > To send out the TxAasyncStart, we have to intercept the async > invocation to send out the event. It's could be a challenge for us to > list all the async invocation. >=20 > Willem Jiang >=20 > Twitter: willemjiang > Weibo: =BD=AA=C4=FEwillem >=20 > On Tue, Jul 30, 2019 at 8:40 AM Willem Jiang = wrote: >>=20 >> According to the feedback for PR, I think we need to rethink about = the >> SagaEnd implementation in the Async invocation scenario. Normally = it's >> harmless we close the Saga transaction later, but we need to make = sure >> all the ongoing local transaction are finished. >>=20 >> In the old way, Alpha can know nothing about the start of Async >> Componseable transaction if the TxStartedEvent is not sent, so my >> propose that we introduce a new event TxAsyncStart to tell Alpha = there >> is new Async invocation, so Alpha can keep tracking this Async >> invocation event the Componseable transaction is not started yet. In >> this way we could block the Async invocation if the Saga transaction >> is timeout or close the Saga transaction if all the TxAsyncStart >> transaction is finished. >>=20 >> Any thoughts? >>=20 >> Willem Jiang >>=20 >> Twitter: willemjiang >> Weibo: =BD=AA=C4=FEwillem >>=20 >> On Mon, Jul 29, 2019 at 5:32 PM Willem Jiang = wrote: >>>=20 >>> Export the low level API could introduce some error if the user >>> doesn't use the API rightly. >>> My suggestion is we just >>> BTW, I submit a PR[1] to address this issue in a simple way (But we >>> still need to tell user what's the right way to configure the >>> annotation attribute). >>>=20 >>> [1]https://github.com/apache/servicecomb-pack/pull/517 >>>=20 >>> Willem Jiang >>>=20 >>> Twitter: willemjiang >>> Weibo: =BD=AA=C4=FEwillem >>>=20 >>> On Thu, Jul 25, 2019 at 8:44 PM Daniel Qian = wrote: >>>>=20 >>>> Hi Zhang Lei, >>>>=20 >>>> What I'm trying to say is to provide a way for user to send >>>> TxEndedEvent, TxAbortedEvent, TxCompensatedEvent, SagaEndedEvent = ... >>>> explicitly on Omega side. >>>> Because current implementation doesn't support following = situation(async): >>>>=20 >>>> @Compensable(compensationMethod=3D"rollbackFoo") >>>> public void foo() { >>>> new Thread(() -> /* local tx goes here */).start(); >>>> // TxEndedEvent sent when returns, it's too early >>>> } >>>>=20 >>>> public void rollbackFoo() { >>>> new Thread(() -> /* compensation goes here*/).start(); >>>> // TxCompensatedEvent sent when returns, it's too early >>>> } >>>>=20 >>>> @SagaStart >>>> public void bar() { >>>> new Thread(() -> /* call other service goes here */).start(); >>>> // SagaEndedEvent sent when returns, it's too early >>>> } >>>>=20 >>>> I suggest providing a helper class, called omega or something else, >>>> user can use it to send TxEndedEvent, TxAbortedEvent, >>>> TxCompensatedEvent, SagaEndedEvent, etc. So the code goes like = this: >>>>=20 >>>> @Compensable(async=3Dtrue, compensationMethod=3D"rollbackFoo", >>>> compensationAsync=3Dtrue) >>>> public void foo() { >>>> TransactionContext txContext =3D = omegaContext.getTransactionContext(); >>>> new Thread(() -> { >>>> try { >>>> /* local tx goes here */ >>>> omega.txEnded(txContext); >>>> } catch(Exception e) { >>>> omega.txAborted(txContext); >>>> } >>>> }).start(); >>>> } >>>>=20 >>>> public void rollbackFoo() { >>>> TransactionContext txContext =3D = omegaContext.getTransactionContext(); >>>> new Thread(() -> { >>>> /*compensation goes here*/ >>>> omega.txCompensated() >>>> }).start(); >>>> } >>>>=20 >>>> @SagaStart(async=3Dtrue) >>>> public void bar() { >>>> TransactionContext txContext =3D = omegaContext.getTransactionContext(); >>>> new Thread(() -> { >>>> /* call other service goes here */ >>>> try { >>>> omega.sagaEnded(txContext); >>>> } catch (Exception e) { >>>> omega.sagaAborted(txContext); >>>> } >>>> }).start(); >>>> } >>>>=20 >>>>=20 >>>> Zhang Lei =D3=DA2019=C4=EA7=D4=C225=C8=D5=D6=DC= =CB=C4 =CF=C2=CE=E74:46=D0=B4=B5=C0=A3=BA >>>>=20 >>>>=20 >>>> Zhang Lei =D3=DA2019=C4=EA7=D4=C225=C8=D5=D6=DC= =CB=C4 =CF=C2=CE=E74:46=D0=B4=B5=C0=A3=BA >>>>>=20 >>>>> Hi, Daniel Qian >>>>>=20 >>>>> Are you talking about the asynchronous problem with the @SagaStart = and @Compensable methods on the Omega side? I think this is a typical = long transaction scene. >>>>>=20 >>>>> Alpha based on Actor model has implemented asynchronous processing = of Omega and Alpha, The event sent to Alpha needs to ensure that all = child transactions have been executed before sending SagaEndedEvent or = SagaAbortedEvent. >>>>>=20 >>>>> Lei Zhang >>>>>=20 >>>>>> =D4=DA 2019=C4=EA7=D4=C220=C8=D5=A3=AC=CF=C2=CE=E79:49=A3=ACDaniel = Qian =D0=B4=B5=C0=A3=BA >>>>>>=20 >>>>>> After look into SCB-163, SCB-1385 and SCB-1386 I have some = thoughts on Saga >>>>>> involved in async invocation. >>>>>> Current implementation is basically based on sync invocation, = there are >>>>>> some assumption: >>>>>>=20 >>>>>> 1. When @SagaStart method returns, the Saga finished. >>>>>> 2. When @Compensable method returns/throws exception, the Local = Tx >>>>>> succeeds/failed. >>>>>> 3. When compensationMethod returns, the Local Tx is compensated. >>>>>>=20 >>>>>> Even if considering what SCB-100 provided: >>>>>>=20 >>>>>> 1. Add @OmegaContextAware annotation enabling >>>>>> java.util.concurrent.Executor inject OmegaConext into threads it >>>>>> manages/spawns >>>>>> 2. Make OmegaContext use InheritableThreadLocal field let child = thread >>>>>> inherit parent thread's Local Tx info >>>>>>=20 >>>>>> There are still some limitations: >>>>>>=20 >>>>>> 1. @OmegaContextAware is only viable if you use spring framework >>>>>> 2. @OmegaContextAware and OmegaContext's InheritableThreadLocal = field >>>>>> assuming that the calling thread or initator thread has Local Tx = info. >>>>>>=20 >>>>>>=20 >>>>>> What if user code use producer-consumer pattern in which >>>>>> InheritableThreadLocal can't work? >>>>>> What if user code use a thread scheduling library which we cannot = use >>>>>> @OmegaContextAware,RxJava and Reactor, for example? >>>>>> I think we could provide some low-level APIs that user code can = manualy >>>>>> starts/ends Saga and Local Tx, something like below: >>>>>>=20 >>>>>> TxContext context =3D omega.startSaga(); >>>>>> TxContext subTxContext =3D omega.startTx(TxContext = parentTxContext); >>>>>> omega.endTx(TxContext); >>>>>> omega.abortTx(TxContext); >>>>>> omega.abortSaga(TxContext); >>>>>> omega.endSaga(TxContext); >>>>>>=20 >>>>>> TxContext is just a immutable dto like this: >>>>>>=20 >>>>>> public class TxContext { >>>>>> private final String globalTxId; >>>>>> private final String localTxId; >>>>>> } >>>>>>=20 >>>>>> Above is a just a rough idea. So any thoughts? >>>>>> -- >>>>>> Daniel Qian >>>>>>=20 >>>>>> =B2=A9=BF=CD=A3=BAhttps://segmentfault.com/u/chanjarster >>>>>> github=A3=BAhttps://github.com/chanjarster >>>>>=20 >>>>=20 >>>>=20 >>>> -- >>>> Daniel Qian >>>>=20 >>>> =B2=A9=BF=CD=A3=BAhttps://segmentfault.com/u/chanjarster >>>> github=A3=BAhttps://github.com/chanjarster