123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129openRresulttypeconfiguration={stateless:bool}letconfiguration?(stateless=false)()={stateless}moduleS=SigsmoduleMake(Scheduler:S.SCHED)(IO:S.IOwithtype'at='aScheduler.s)(Flow:S.FLOWwithtype'afiber='aScheduler.s)(Uid:S.UID)(Ref:S.REF)=structletsrc=Logs.Src.create"push"moduleLog=(valLogs.src_logsrc:Logs.LOG)openSchedulerlet(>>=)xf=IO.bindxfletreturnx=IO.returnxlet(>>|)xf=x>>=funx->return(fx)letsched=S.{bind=(funxf->inj(prjx>>=funx->prj(fx)));return=(funx->inj(returnx));}letfailexn=inj(IO.failexn)letio=S.{recv=(funflowraw->inj(Flow.recvflowraw));send=(funflowraw->inj(Flow.sendflowraw));pp_error=Flow.pp_error;}letpush?(uses_git_transport=false)~capabilities:my_capscmds~hostpathflowstoreaccess{stateless}pack=letfiberctx=letopenSmartinlet*()=ifuses_git_transportthensendctxproto_request(Proto_request.receive_pack~host~version:1path)elsereturn()inlet*v=recvctxadvertised_refsinContext.replace_their_capsctx(Smart.Advertised_refs.capabilitiesv);return(Smart.Advertised_refs.map~fuid:Uid.of_hex~fref:Ref.vv)inletctx=Smart.Context.make~my_capsinSmart_flow.runschedfailioflow(fiberctx)|>prj>>=funadvertised_refs->Pck.commandssched~capabilities:my_caps~equal:Ref.equal~deref:access.Sigs.derefstorecmds(Smart.Advertised_refs.refsadvertised_refs)|>prj>>=function|None->Smart_flow.runschedfailioflowSmart.(sendctxflush())|>prj>>=fun()->return()|Somecmds->(Smart_flow.runschedfailioflowSmart.(sendctxcommands(Commands.map~fuid:Uid.to_hex~fref:Ref.to_stringcmds))|>prj>>=fun()->letexclude,sources=Pck.get_limits~compare:Uid.compare(Smart.Advertised_refs.refsadvertised_refs)(Smart.Commands.commandscmds)inPck.get_uncommon_objectssched~compare:Uid.compareaccessstore~exclude~sources|>prj>>=funuids->Log.debug(funm->m"Prepare a pack of %d object(s)."(List.lengthuids));letstream=packuidsinletside_band=Smart.Context.is_cap_sharedctx`Side_band||Smart.Context.is_cap_sharedctx`Side_band_64kinletpack=Smart.send_pack~statelessside_bandinletrecgo()=stream()>>=function|None->letreport_status=Smart.Context.is_cap_sharedctx`Report_statusinLog.debug(funm->m"report-status capability: %b."report_status);ifreport_statusthenSmart_flow.runschedfailioflowSmart.(recvctx(statusside_band))|>prj>>|Smart.Status.map~f:Ref.velseifuses_git_transportthenSmart_flow.runschedfailioflowSmart.(recvctxrecv_flush)|>prj>>=fun()->letcmds=List.mapR.ok(Smart.Commands.commandscmds)inreturn(Smart.Status.vcmds)elseletcmds=List.mapR.ok(Smart.Commands.commandscmds)inreturn(Smart.Status.vcmds)|Somepayload->Smart_flow.runschedfailioflowSmart.(sendctxpackpayload)|>prj>>=fun()->go()ingo()>>=funstatus->matchSmart.Status.to_resultstatuswith|Ok()->Log.debug(funm->m"Push is done!");Log.info(funm->m"%a"Smart.Status.pp(Smart.Status.map~f:Ref.to_stringstatus));return()|Errorerr->Log.err(funm->m"Push got an error: %s"err);return())end