-
Notifications
You must be signed in to change notification settings - Fork 327
/
satellite.go
78 lines (70 loc) · 1.95 KB
/
satellite.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Copyright (C) 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package master
import (
"context"
"sync"
"github.com/google/gapid/core/event/task"
)
type satellite struct {
lock sync.Mutex
info *Satellite
issues chan issue
}
// issue is used to package a command with a channel to feed the result of
// handling the command.
type issue struct {
command *Command
result chan error
}
func newSatellite(ctx context.Context, name string, services ServiceList) *satellite {
return &satellite{
info: &Satellite{
Name: name,
Services: &services,
},
issues: make(chan issue),
}
}
// processCommands reads the issues from the channel and hands them to the command handler, sending
// the result back through the issue channel.
func (sat *satellite) processCommands(ctx context.Context, handler CommandHandler) {
for {
select {
case <-task.ShouldStop(ctx):
return
case i := <-sat.issues:
i.result <- handler(ctx, i.command)
close(i.result)
}
}
}
// sendCommand posts an issue for the command into the channel, then blocks until it gets a result.
func (sat *satellite) sendCommand(ctx context.Context, command *Command) {
result := make(chan error)
sat.lock.Lock()
if sat.issues != nil {
sat.issues <- issue{command: command, result: result}
}
sat.lock.Unlock()
err := <-result
if err != nil {
sat.lock.Lock()
if sat.issues != nil {
close(sat.issues)
sat.issues = nil
}
sat.lock.Unlock()
}
}