mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2025-12-23 22:29:59 -05:00
163 lines
5.9 KiB
Go
163 lines
5.9 KiB
Go
package runner
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net"
|
|
"net/http"
|
|
|
|
ogrpc "github.com/opencloud-eu/opencloud/pkg/service/grpc"
|
|
ohttp "github.com/opencloud-eu/opencloud/pkg/service/http"
|
|
"github.com/opencloud-eu/reva/v2/cmd/revad/runtime"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
// NewGoMicroGrpcServerRunner creates a new runner based on the provided go-micro's
|
|
// GRPC service. The service is expected to be created via
|
|
// "github.com/opencloud-eu/opencloud/pkg/service/grpc".NewService(...) function
|
|
//
|
|
// The runner will behave as described:
|
|
// * The task is to start a server and listen for connections. If the server
|
|
// can't start, the task will finish with that error.
|
|
// * The stopper will call the server's stop method and send the result to
|
|
// the task.
|
|
// * The stopper will run asynchronously because the stop method could take a
|
|
// while and we don't want to block
|
|
func NewGoMicroGrpcServerRunner(name string, server ogrpc.Service, opts ...Option) *Runner {
|
|
httpCh := make(chan error, 1)
|
|
r := New(name, func() error {
|
|
// start the server and return if it fails
|
|
if err := server.Server().Start(); err != nil {
|
|
return err
|
|
}
|
|
return <-httpCh // wait for the result
|
|
}, func() {
|
|
// stop implies deregistering and waiting for request to finish,
|
|
// so don't block
|
|
go func() {
|
|
httpCh <- server.Server().Stop() // stop and send result through channel
|
|
close(httpCh)
|
|
}()
|
|
}, opts...)
|
|
return r
|
|
}
|
|
|
|
// NewGoMicroHttpServerRunner creates a new runner based on the provided go-micro's
|
|
// HTTP service. The service is expected to be created via
|
|
// "github.com/opencloud-eu/opencloud/pkg/service/http".NewService(...) function
|
|
//
|
|
// The runner will behave as described:
|
|
// * The task is to start a server and listen for connections. If the server
|
|
// can't start, the task will finish with that error.
|
|
// * The stopper will call the server's stop method and send the result to
|
|
// the task.
|
|
// * The stopper will run asynchronously because the stop method could take a
|
|
// while and we don't want to block
|
|
func NewGoMicroHttpServerRunner(name string, server ohttp.Service, opts ...Option) *Runner {
|
|
httpCh := make(chan error, 1)
|
|
r := New(name, func() error {
|
|
// start the server and return if it fails
|
|
if err := server.Server().Start(); err != nil {
|
|
return err
|
|
}
|
|
return <-httpCh // wait for the result
|
|
}, func() {
|
|
// stop implies deregistering and waiting for request to finish,
|
|
// so don't block
|
|
go func() {
|
|
httpCh <- server.Server().Stop() // stop and send result through channel
|
|
close(httpCh)
|
|
}()
|
|
}, opts...)
|
|
return r
|
|
}
|
|
|
|
// NewGolangHttpServerRunner creates a new runner based on the provided HTTP server.
|
|
// The HTTP server is expected to be created via
|
|
// "github.com/opencloud-eu/opencloud/pkg/service/debug".NewService(...) function
|
|
// and it's expected to be a regular golang HTTP server
|
|
//
|
|
// The runner will behave as described:
|
|
// * The task starts a server and listen for connections. If the server
|
|
// can't start, the task will finish with that error. If the server is shutdown
|
|
// the task will wait for the shutdown to return that result (task won't finish
|
|
// immediately, but wait until shutdown returns)
|
|
// * The stopper will call the server's shutdown method and send the result to
|
|
// the task. The stopper will wait up to 5 secs for the shutdown.
|
|
// * The stopper will run asynchronously because the shutdown could take a
|
|
// while and we don't want to block
|
|
func NewGolangHttpServerRunner(name string, server *http.Server, opts ...Option) *Runner {
|
|
debugCh := make(chan error, 1)
|
|
r := New(name, func() error {
|
|
// start listening and return if the error is NOT ErrServerClosed.
|
|
// ListenAndServe will always return a non-nil error.
|
|
// We need to wait and get the result of the Shutdown call.
|
|
// App shouldn't exit until Shutdown has returned.
|
|
if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
|
return err
|
|
}
|
|
// wait for the shutdown and return the result
|
|
return <-debugCh
|
|
}, func() {
|
|
// Since Shutdown might take some time, don't block
|
|
go func() {
|
|
// Use the DefaultInterruptDuration or InterruptDuration as the shutdown timeout.
|
|
shutdownCtx, cancel := context.WithTimeout(context.Background(), DefaultInterruptDuration)
|
|
defer cancel()
|
|
|
|
debugCh <- server.Shutdown(shutdownCtx)
|
|
close(debugCh)
|
|
}()
|
|
}, opts...)
|
|
|
|
return r
|
|
}
|
|
|
|
// NewGolangGrpcServerRunner creates a new runner based on the provided GRPC
|
|
// server. The GRPC server is expected to be a regular golang GRPC server,
|
|
// created via "google.golang.org/grpc".NewServer(...)
|
|
// A listener also needs to be provided for the server to listen there.
|
|
//
|
|
// The runner will just start the GRPC server in the listener, and the server
|
|
// will be gracefully stopped when interrupted
|
|
func NewGolangGrpcServerRunner(name string, server *grpc.Server, listener net.Listener, opts ...Option) *Runner {
|
|
r := New(name, func() error {
|
|
return server.Serve(listener)
|
|
}, func() {
|
|
// Since GracefulStop might take some time, don't block
|
|
go func() {
|
|
server.GracefulStop()
|
|
}()
|
|
}, opts...)
|
|
|
|
return r
|
|
}
|
|
|
|
// NewRevaServiceRunner creates a new runner based on the provided reva RevaDrivenServer
|
|
// The runner will behave as described:
|
|
// * The task is to start a server and listen for connections. If the server
|
|
// can't start, the task will finish with that error.
|
|
// * The stopper will call the server's stop method and send the result to
|
|
// the task.
|
|
// * The stopper will run asynchronously because the stop method could take a
|
|
// while and we don't want to block
|
|
func NewRevaServiceRunner(name string, server runtime.RevaDrivenServer, opts ...Option) *Runner {
|
|
httpCh := make(chan error, 1)
|
|
r := New(name, func() error {
|
|
// start the server and return if it fails
|
|
if err := server.Start(); err != nil {
|
|
return err
|
|
}
|
|
return <-httpCh // wait for the result
|
|
}, func() {
|
|
// stop implies deregistering and waiting for the request to finish,
|
|
// so don't block
|
|
go func() {
|
|
httpCh <- server.Stop() // stop and send a result through a channel
|
|
close(httpCh)
|
|
}()
|
|
}, opts...)
|
|
|
|
return r
|
|
}
|