@ -89,8 +89,15 @@ func (a *App) Run() error {
a . mu . Lock ( )
a . mu . Lock ( )
a . instance = instance
a . instance = instance
a . mu . Unlock ( )
a . mu . Unlock ( )
eg , ctx := errgroup . WithContext ( NewContext ( a . ctx , a ) )
sctx := NewContext ( a . ctx , a )
eg , ctx := errgroup . WithContext ( sctx )
wg := sync . WaitGroup { }
wg := sync . WaitGroup { }
for _ , fn := range a . opts . beforeStart {
if err = fn ( sctx ) ; err != nil {
return err
}
}
for _ , srv := range a . opts . servers {
for _ , srv := range a . opts . servers {
srv := srv
srv := srv
eg . Go ( func ( ) error {
eg . Go ( func ( ) error {
@ -102,17 +109,23 @@ func (a *App) Run() error {
wg . Add ( 1 )
wg . Add ( 1 )
eg . Go ( func ( ) error {
eg . Go ( func ( ) error {
wg . Done ( ) // here is to ensure server start has begun running before register, so defer is not needed
wg . Done ( ) // here is to ensure server start has begun running before register, so defer is not needed
return srv . Start ( NewContext ( a . op ts . ctx , a ) )
return srv . Start ( sc tx )
} )
} )
}
}
wg . Wait ( )
wg . Wait ( )
if a . opts . registrar != nil {
if a . opts . registrar != nil {
rctx , rcancel := context . WithTimeout ( ctx , a . opts . registrarTimeout )
rctx , rcancel := context . WithTimeout ( ctx , a . opts . registrarTimeout )
defer rcancel ( )
defer rcancel ( )
if err := a . opts . registrar . Register ( rctx , instance ) ; err != nil {
if err = a . opts . registrar . Register ( rctx , instance ) ; err != nil {
return err
}
}
for _ , fn := range a . opts . afterStart {
if err = fn ( sctx ) ; err != nil {
return err
return err
}
}
}
}
c := make ( chan os . Signal , 1 )
c := make ( chan os . Signal , 1 )
signal . Notify ( c , a . opts . sigs ... )
signal . Notify ( c , a . opts . sigs ... )
eg . Go ( func ( ) error {
eg . Go ( func ( ) error {
@ -123,28 +136,36 @@ func (a *App) Run() error {
return a . Stop ( )
return a . Stop ( )
}
}
} )
} )
if err : = eg . Wait ( ) ; err != nil && ! errors . Is ( err , context . Canceled ) {
if err = eg . Wait ( ) ; err != nil && ! errors . Is ( err , context . Canceled ) {
return err
return err
}
}
return nil
for _ , fn := range a . opts . afterStop {
err = fn ( sctx )
}
return err
}
}
// Stop gracefully stops the application.
// Stop gracefully stops the application.
func ( a * App ) Stop ( ) error {
func ( a * App ) Stop ( ) ( err error ) {
sctx := NewContext ( a . ctx , a )
for _ , fn := range a . opts . beforeStop {
err = fn ( sctx )
}
a . mu . Lock ( )
a . mu . Lock ( )
instance := a . instance
instance := a . instance
a . mu . Unlock ( )
a . mu . Unlock ( )
if a . opts . registrar != nil && instance != nil {
if a . opts . registrar != nil && instance != nil {
ctx , cancel := context . WithTimeout ( NewContext ( a . ctx , a ) , a . opts . registrarTimeout )
ctx , cancel := context . WithTimeout ( NewContext ( a . ctx , a ) , a . opts . registrarTimeout )
defer cancel ( )
defer cancel ( )
if err : = a . opts . registrar . Deregister ( ctx , instance ) ; err != nil {
if err = a . opts . registrar . Deregister ( ctx , instance ) ; err != nil {
return err
return err
}
}
}
}
if a . cancel != nil {
if a . cancel != nil {
a . cancel ( )
a . cancel ( )
}
}
return nil
return err
}
}
func ( a * App ) buildInstance ( ) ( * registry . ServiceInstance , error ) {
func ( a * App ) buildInstance ( ) ( * registry . ServiceInstance , error ) {