1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* Copyright (c) 2018-2021 Nomadic Labs, <contact@nomadic-labs.com> *)(* Copyright (c) 2023 Trili Tech <contact@trili.tech> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)openLwt.SyntaxexceptionNone_successfulofstringletnever_ending()=fst(Lwt.wait())(* A worker launcher, takes a cancel callback to call upon *)letworkername~on_event~run~cancel=letstop,stopper=Lwt.wait()inletfaile=Lwt.finalize(fun()->on_eventname(`Failed(Printf.sprintf"Exception: %s"(Printexc.to_stringe))))cancelinlet*()=on_eventname`Startedinletp=Lwt.catchrunfailinLwt.on_terminationp(Lwt.wakeupstopper);let*()=stopinLwt.catch(fun()->on_eventname`Ended)(fun_->Lwt.return_unit)letworkername~on_event~run~cancel=Lwt.no_cancel(workername~on_event~run~cancel)letpick_successful=function|[]->raise(Invalid_argument"Lwt_utils.pick_successful [] would return a promise that is \
pending forever")|promises->letpromise,resolver=Lwt.task()inletpending_count=ref(List.lengthpromises)inleton_successvalue=tryLwt.wakeup_laterresolvervaluewithStdlib.Invalid_argument_->(* If the promise is already resolved, the raised
exception [Stdlib.Invalid_argument _] is caught
and ignored. *)()inleton_failure_exn=decrpending_count;if!pending_count=0thenLwt.wakeup_later_exnresolver(None_successful"All pending tasks were rejected, canceled or did not pass \n\
the success criteria.")else()inList.iter(funpromise->Lwt.on_successpromiseon_success;Lwt.on_failurepromiseon_failure)promises;letcancel_allpromises=List.iterLwt.cancelpromisesinLwt.on_successpromise(fun_->cancel_allpromises);Lwt.on_cancelpromise(fun()->cancel_allpromises);promise