-
Notifications
You must be signed in to change notification settings - Fork 79
/
handlers.go
60 lines (50 loc) · 1.36 KB
/
handlers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package exec
import (
"time"
log "github.com/Sirupsen/logrus"
"github.com/luizalabs/teresa/pkg/goutil"
execpb "github.com/luizalabs/teresa/pkg/protobuf/exec"
"github.com/luizalabs/teresa/pkg/server/database"
"google.golang.org/grpc"
)
const keepAliveMessage = "\u200B" // Zero width space
type Service struct {
ops Operations
keepAliveTimeout time.Duration
}
func (s *Service) Command(req *execpb.CommandRequest, stream execpb.Exec_CommandServer) error {
ctx := stream.Context()
u := ctx.Value("user").(*database.User)
log.Infof("Received exec: cmd <%v>, user %v:", req.Command, u)
rc, errChan := s.ops.RunCommand(ctx, u, req.AppName, req.Command...)
if rc == nil {
return <-errChan
}
defer rc.Close()
cmdMsgs, cmdErrCh := goutil.LineGenerator(rc)
var msg string
for {
select {
case <-time.After(s.keepAliveTimeout):
msg = keepAliveMessage
case err := <-errChan:
return err
case err := <-cmdErrCh:
return err
case m, ok := <-cmdMsgs:
if !ok {
return nil
}
msg = m
}
if err := stream.Send(&execpb.CommandResponse{Text: msg + "\n"}); err != nil {
return err
}
}
}
func (s *Service) RegisterService(grpcServer *grpc.Server) {
execpb.RegisterExecServer(grpcServer, s)
}
func NewService(ops Operations, keepAliveTimeout time.Duration) *Service {
return &Service{ops: ops, keepAliveTimeout: keepAliveTimeout}
}