-
Notifications
You must be signed in to change notification settings - Fork 1
/
io.go
183 lines (151 loc) · 3.35 KB
/
io.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package elio
import (
"context"
"fmt"
"net"
"os"
"os/signal"
"runtime"
"strings"
"time"
cmap "github.com/orcaman/concurrent-map"
"go.uber.org/atomic"
)
const (
// DefaultInterval default interval
DefaultInterval time.Duration = 20 * time.Millisecond
)
// https://blog.alexellis.io/inject-build-time-vars-golang/
// Action is an action that occurs after the completion of an event.
type Action int
const (
// None indicates that no action should occur following an event.
None Action = iota
// Listen listen.
Listen
// Shut close the listen.
Shut
// SafeTermiate close the listen and exit when no user.
SafeTermiate
// Termiate terminate the server.
Termiate
// TermiateAfter5m shutdown after 5 minute.
TermiateAfter5m
// CloseAll disconnect all connections.
CloseAll
// Close disconnect connection.
Close
)
// Io IO
type Io struct {
Listener *Listener //net.Listener
Config ConfigIo
Host *IoHost
Service Service
ioModel IoModel
InAddr atomic.String //*net.TCPAddr
InCount atomic.Int32
sessionCmap cmap.ConcurrentMap
ctx context.Context
cancel context.CancelFunc
action Action
}
// NewIo new server
func NewIo(h *IoHost, c ConfigIo, s Service) *Io {
if io := new(Io); nil != io {
io.Host = h
io.Service = s
io.ctx, io.cancel = context.WithCancel(context.Background())
io.Listener = newListener(c.InModel, c.InReusePort)
if i := GenIO(c.InModel); nil != i {
i.SetIo(io)
io.Config = c
io.Init()
return io
}
}
return nil
}
func (i *Io) String() string {
return fmt.Sprintf("Io::%p", i)
}
// Run run Io
func (i *Io) Run(addr *net.TCPAddr) (ok bool) {
AppInfo().Str(LogObject, i.String()).
Msgf("Io.run url:%s begin", i.Config.InURL)
if ok = i.Listen(addr); ok {
i.ioModel.Run()
}
return ok
}
// Listen listen Io
func (i *Io) Listen(addr *net.TCPAddr) (ok bool) {
return i.ioModel.Listen(addr.String())
}
// Shut shut
func (i *Io) Shut() {
i.ioModel.Shut()
}
// End end
func (i *Io) End() {
defer func() {
i.Host.Wg.Done()
}()
//i.cancel()
i.ioModel.End()
//i.Host.Terminate()
}
// Shutdown shutdown
func (i *Io) Shutdown(n *Session, how int) error {
return i.ioModel.Shutdown(n, how)
}
// Terminate terminate
func (i *Io) Terminate() {
AppInfo().Str(LogObject, i.String()).Msg("terminate Io")
i.ioModel.Shut()
i.ioModel.End()
}
// Init init
func (i *Io) Init() {
i.sessionCmap = cmap.New()
}
// GetIoModel get IO model
func (i *Io) GetIoModel() IoModel {
return i.ioModel
}
// SetIoModel set IO model
func (i *Io) SetIoModel(ioModel IoModel) {
i.ioModel = ioModel
}
// GetBaseAndConfig get base and config
func GetBaseAndConfig() (base string, config string) {
//if 1 < len(os.Args) {
// base = os.Args[0]
// config = GetBasename(os.Args[1])
//} else {
base = GetBasename(os.Args[0])
var builder strings.Builder
builder.WriteString(base)
builder.WriteString(".json")
config = builder.String()
//}
return base, config
}
// StartUp start up
func StartUp() {
runtime.GOMAXPROCS(runtime.NumCPU() * 2)
if err := SetLimit(); nil != err {
AppError().Err(err).Msg("failed to set.limit")
}
}
// StopDown stop down
func StopDown(exit func()) {
var gracefulStop = make(chan os.Signal)
signal.Notify(gracefulStop, SigTerm)
signal.Notify(gracefulStop, SigInt)
go func() {
sig := <-gracefulStop
AppInfo().Msgf("caught sig:%+v\n", sig)
exit()
}()
}