-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient.go
More file actions
90 lines (76 loc) · 1.97 KB
/
client.go
File metadata and controls
90 lines (76 loc) · 1.97 KB
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
79
80
81
82
83
84
85
86
87
88
89
90
package simplestdioplugin
import (
"os"
"sync"
)
type PluginData struct {
Router map[string]func(data []byte) ([]byte, error)
Stdin *os.File
Stdout *os.File
}
func (plugin *PluginData) readInput() (id []byte, data []byte, err error) {
result, err := readAll(plugin.Stdin)
if err != nil {
return nil, nil, err
}
return result.uuid, result.data, nil
}
func (plugin *PluginData) writeOutput(id []byte, data []byte) error {
return writeAll(id, data, plugin.Stdout)
}
func (plugin *PluginData) writeError(id []byte, data string) error {
return writeAll(id, []byte(data), plugin.Stdout)
}
func NewPluginClient(Router map[string]func(json []byte) ([]byte, error), Stdin *os.File, Stdout *os.File) PluginData {
return PluginData{Router: Router, Stdin: Stdin, Stdout: Stdout}
}
func PluginServe(plugin PluginData, max_conn ...int) error {
max_concurrent := 1000
if len(max_conn) > 0 {
max_concurrent = max_conn[0]
}
mut := sync.RWMutex{}
concurrent := 0
for {
id, data, err := plugin.readInput()
if err != nil {
_ = plugin.writeError(id, "readInput error: "+err.Error())
continue
}
mut.RLock()
if concurrent >= max_concurrent {
_ = plugin.writeError(id, "concurrent error: MAX CONCURRENT command reached")
mut.RUnlock()
continue
}
mut.RUnlock()
input, err := decodeMessage(data)
if err != nil {
_ = plugin.writeError(id, "decode message error: "+err.Error())
continue
}
mut.Lock()
concurrent += 1
mut.Unlock()
go func() {
defer func() {
mut.Lock()
concurrent -= 1
mut.Unlock()
}()
function := plugin.Router[input.Function]
if function != nil {
result, err := function(input.Data)
if err != nil {
_ = plugin.writeError(id, "error func: "+err.Error())
} else {
if err := plugin.writeOutput(id, result); err != nil {
_ = plugin.writeError(id, "error write: "+err.Error())
}
}
} else {
_ = plugin.writeError(id, "error func: "+input.Function+" not found")
}
}()
}
}