@@ -78,7 +78,7 @@ function layerTestFor(state: {
7878 remoteStatusRefreshUpstreamValues ?: Array < boolean | undefined > ;
7979 backgroundWorkEnabled ?: boolean ;
8080 automaticFetchInterval ?: Effect . Effect < Duration . Duration > ;
81- beforeRemoteStatus ?: Effect . Effect < void > ;
81+ beforeRemoteStatus ?: Effect . Effect < void , GitManagerError > ;
8282} ) {
8383 return VcsStatusBroadcaster . layer . pipe (
8484 Layer . provideMerge ( NodeServices . layer ) ,
@@ -754,4 +754,48 @@ describe("VcsStatusBroadcaster", () => {
754754 assert . equal ( state . remoteStatusCalls , 3 ) ;
755755 } ) . pipe ( Effect . provide ( layerTestFor ( state ) ) ) ;
756756 } ) ;
757+ it . effect ( "a failed refresh releases interrupted waiters and runs the shared follow-up" , ( ) => {
758+ const state : Parameters < typeof layerTestFor > [ 0 ] = {
759+ currentLocalStatus : baseLocalStatus ,
760+ currentRemoteStatus : remoteStatusWithPr ,
761+ localStatusCalls : 0 ,
762+ remoteStatusCalls : 0 ,
763+ localInvalidationCalls : 0 ,
764+ remoteInvalidationCalls : 0 ,
765+ } ;
766+
767+ return Effect . gen ( function * ( ) {
768+ const broadcaster = yield * VcsStatusBroadcaster . VcsStatusBroadcaster ;
769+ const started = yield * Deferred . make < void > ( ) ;
770+ const release = yield * Deferred . make < void > ( ) ;
771+ state . beforeRemoteStatus = Deferred . succeed ( started , undefined ) . pipe (
772+ Effect . andThen ( Deferred . await ( release ) ) ,
773+ Effect . andThen (
774+ Effect . fail (
775+ new GitManagerError ( {
776+ operation : "VcsStatusBroadcaster.test" ,
777+ cwd : "/repo" ,
778+ detail : "remote status failed" ,
779+ } ) ,
780+ ) ,
781+ ) ,
782+ ) ;
783+ const first = yield * broadcaster . refreshStatus ( "/repo" ) . pipe ( Effect . exit , Effect . forkScoped ) ;
784+ yield * Deferred . await ( started ) ;
785+ const interrupted = yield * broadcaster
786+ . refreshStatus ( "/repo" )
787+ . pipe ( Effect . forkScoped ( { startImmediately : true } ) ) ;
788+ const remaining = yield * broadcaster
789+ . refreshStatus ( "/repo" )
790+ . pipe ( Effect . forkScoped ( { startImmediately : true } ) ) ;
791+ yield * Fiber . interrupt ( interrupted ) ;
792+ state . beforeRemoteStatus = Effect . void ;
793+ yield * Deferred . succeed ( release , undefined ) ;
794+ assert . isTrue ( Exit . isFailure ( yield * Fiber . join ( first ) ) ) ;
795+ assert . deepStrictEqual ( ( yield * Fiber . join ( remaining ) ) . pr , remoteStatusWithPr . pr ) ;
796+ assert . equal ( state . remoteInvalidationCalls , 2 ) ;
797+ yield * broadcaster . refreshStatus ( "/repo" ) ;
798+ assert . equal ( state . remoteInvalidationCalls , 3 ) ;
799+ } ) . pipe ( Effect . provide ( layerTestFor ( state ) ) ) ;
800+ } ) ;
757801} ) ;
0 commit comments