mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-06 07:57:27 +08:00
feat: report worker system information to the master
This commit is contained in:
@@ -3,6 +3,7 @@ package boomer
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@@ -181,7 +182,7 @@ func (c *grpcClient) start() (err error) {
|
|||||||
func (c *grpcClient) register(ctx context.Context) error {
|
func (c *grpcClient) register(ctx context.Context) error {
|
||||||
ctx, cancel := context.WithTimeout(ctx, time.Second)
|
ctx, cancel := context.WithTimeout(ctx, time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
res, err := c.Register(ctx, &messager.RegisterRequest{NodeID: c.identity})
|
res, err := c.Register(ctx, &messager.RegisterRequest{NodeID: c.identity, Os: runtime.GOOS, Arch: runtime.GOARCH})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -212,6 +213,9 @@ func (c *grpcClient) newBiStreamClient() (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// reset failCount
|
||||||
|
atomic.StoreInt32(&c.failCount, 0)
|
||||||
|
// set bidirectional stream client
|
||||||
c.config.setBiStreamClient(biStream)
|
c.config.setBiStreamClient(biStream)
|
||||||
println("successful to establish bidirectional stream with master, press Ctrl+c to quit.")
|
println("successful to establish bidirectional stream with master, press Ctrl+c to quit.")
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ type StreamRequest struct {
|
|||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
|
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
|
||||||
Data map[string]int64 `protobuf:"bytes,2,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
|
NodeID string `protobuf:"bytes,2,opt,name=nodeID,proto3" json:"nodeID,omitempty"`
|
||||||
NodeID string `protobuf:"bytes,3,opt,name=NodeID,proto3" json:"NodeID,omitempty"`
|
Data map[string][]byte `protobuf:"bytes,3,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *StreamRequest) Reset() {
|
func (x *StreamRequest) Reset() {
|
||||||
@@ -69,13 +69,6 @@ func (x *StreamRequest) GetType() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *StreamRequest) GetData() map[string]int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Data
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *StreamRequest) GetNodeID() string {
|
func (x *StreamRequest) GetNodeID() string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.NodeID
|
return x.NodeID
|
||||||
@@ -83,16 +76,23 @@ func (x *StreamRequest) GetNodeID() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *StreamRequest) GetData() map[string][]byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Data
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type StreamResponse struct {
|
type StreamResponse struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
|
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
|
||||||
Profile []byte `protobuf:"bytes,2,opt,name=profile,proto3" json:"profile,omitempty"`
|
NodeID string `protobuf:"bytes,2,opt,name=nodeID,proto3" json:"nodeID,omitempty"`
|
||||||
Data map[string]int64 `protobuf:"bytes,3,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
|
Profile []byte `protobuf:"bytes,3,opt,name=profile,proto3" json:"profile,omitempty"`
|
||||||
NodeID string `protobuf:"bytes,4,opt,name=NodeID,proto3" json:"NodeID,omitempty"`
|
Tasks []byte `protobuf:"bytes,4,opt,name=tasks,proto3" json:"tasks,omitempty"`
|
||||||
Tasks []byte `protobuf:"bytes,5,opt,name=tasks,proto3" json:"tasks,omitempty"`
|
Data map[string][]byte `protobuf:"bytes,5,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *StreamResponse) Reset() {
|
func (x *StreamResponse) Reset() {
|
||||||
@@ -134,20 +134,6 @@ func (x *StreamResponse) GetType() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *StreamResponse) GetProfile() []byte {
|
|
||||||
if x != nil {
|
|
||||||
return x.Profile
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *StreamResponse) GetData() map[string]int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Data
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *StreamResponse) GetNodeID() string {
|
func (x *StreamResponse) GetNodeID() string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.NodeID
|
return x.NodeID
|
||||||
@@ -155,6 +141,13 @@ func (x *StreamResponse) GetNodeID() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *StreamResponse) GetProfile() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Profile
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (x *StreamResponse) GetTasks() []byte {
|
func (x *StreamResponse) GetTasks() []byte {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Tasks
|
return x.Tasks
|
||||||
@@ -162,12 +155,21 @@ func (x *StreamResponse) GetTasks() []byte {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *StreamResponse) GetData() map[string][]byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Data
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type RegisterRequest struct {
|
type RegisterRequest struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
NodeID string `protobuf:"bytes,1,opt,name=NodeID,proto3" json:"NodeID,omitempty"`
|
NodeID string `protobuf:"bytes,1,opt,name=nodeID,proto3" json:"nodeID,omitempty"`
|
||||||
|
Os string `protobuf:"bytes,2,opt,name=os,proto3" json:"os,omitempty"`
|
||||||
|
Arch string `protobuf:"bytes,3,opt,name=arch,proto3" json:"arch,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RegisterRequest) Reset() {
|
func (x *RegisterRequest) Reset() {
|
||||||
@@ -209,6 +211,20 @@ func (x *RegisterRequest) GetNodeID() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *RegisterRequest) GetOs() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Os
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RegisterRequest) GetArch() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Arch
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type RegisterResponse struct {
|
type RegisterResponse struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@@ -269,7 +285,7 @@ type SignOutRequest struct {
|
|||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
NodeID string `protobuf:"bytes,1,opt,name=NodeID,proto3" json:"NodeID,omitempty"`
|
NodeID string `protobuf:"bytes,1,opt,name=nodeID,proto3" json:"nodeID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SignOutRequest) Reset() {
|
func (x *SignOutRequest) Reset() {
|
||||||
@@ -373,59 +389,61 @@ var file_grpc_proto_messager_proto_rawDesc = []byte{
|
|||||||
0x73, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x65, 0x73,
|
0x73, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x65, 0x73,
|
||||||
0x73, 0x61, 0x67, 0x65, 0x22, 0xaa, 0x01, 0x0a, 0x0d, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52,
|
0x73, 0x61, 0x67, 0x65, 0x22, 0xaa, 0x01, 0x0a, 0x0d, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52,
|
||||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01,
|
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01,
|
||||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x34, 0x0a, 0x04, 0x64, 0x61,
|
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f,
|
||||||
0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61,
|
0x64, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65,
|
||||||
0x67, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
0x49, 0x44, 0x12, 0x34, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
|
||||||
0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61,
|
0x32, 0x20, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
|
||||||
0x12, 0x16, 0x0a, 0x06, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74,
|
||||||
0x52, 0x06, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61,
|
0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61,
|
||||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||||
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||||
0x01, 0x22, 0xdc, 0x01, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70,
|
0x01, 0x22, 0xdc, 0x01, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70,
|
||||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
|
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||||
0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66,
|
0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65,
|
||||||
0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69,
|
0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44,
|
||||||
0x6c, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
|
0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||||
0x32, 0x21, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
|
0x0c, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x61,
|
||||||
0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e,
|
0x73, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73,
|
||||||
0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x4e, 0x6f, 0x64,
|
0x12, 0x35, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21,
|
||||||
0x65, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4e, 0x6f, 0x64, 0x65, 0x49,
|
0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52,
|
||||||
0x44, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c,
|
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72,
|
||||||
0x52, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45,
|
0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45,
|
||||||
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||||
0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
|
0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
|
||||||
0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
|
0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
|
||||||
0x22, 0x29, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
|
0x22, 0x4d, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
|
||||||
0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20,
|
0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20,
|
||||||
0x01, 0x28, 0x09, 0x52, 0x06, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x22, 0x40, 0x0a, 0x10, 0x52,
|
0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x6f,
|
||||||
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x61,
|
||||||
0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63,
|
0x72, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x63, 0x68, 0x22,
|
||||||
0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02,
|
0x40, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x28, 0x0a,
|
0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||||
0x0e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
|
||||||
0x16, 0x0a, 0x06, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||||
0x06, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x22, 0x3f, 0x0a, 0x0f, 0x53, 0x69, 0x67, 0x6e, 0x4f,
|
0x65, 0x22, 0x28, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75,
|
||||||
0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f,
|
0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20,
|
||||||
0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18,
|
0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x22, 0x3f, 0x0a, 0x0f, 0x53,
|
||||||
0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12,
|
||||||
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0xe4, 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x73,
|
0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f,
|
||||||
0x73, 0x61, 0x67, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
|
0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20,
|
||||||
0x12, 0x18, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73,
|
0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0xe4, 0x01, 0x0a,
|
||||||
0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6d, 0x65, 0x73,
|
0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69,
|
||||||
0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73,
|
0x73, 0x74, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52,
|
||||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e, 0x4f,
|
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19,
|
||||||
0x75, 0x74, 0x12, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x69, 0x67,
|
0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
|
||||||
0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6d, 0x65,
|
0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x07, 0x53,
|
||||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73,
|
0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x12, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x1d, 0x42, 0x69, 0x64, 0x69, 0x72,
|
0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||||
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e,
|
0x18, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75,
|
||||||
0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61,
|
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x1d, 0x42,
|
||||||
0x67, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
0x69, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x72, 0x65,
|
||||||
0x1a, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
|
0x61, 0x6d, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x2e, 0x6d,
|
||||||
0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42,
|
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71,
|
||||||
0x0f, 0x5a, 0x0d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x72,
|
0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53,
|
||||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28,
|
||||||
|
0x01, 0x30, 0x01, 0x42, 0x0f, 0x5a, 0x0d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x6d, 0x65, 0x73, 0x73,
|
||||||
|
0x61, 0x67, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -12,20 +12,22 @@ service Message {
|
|||||||
|
|
||||||
message StreamRequest{
|
message StreamRequest{
|
||||||
string type = 1;
|
string type = 1;
|
||||||
map<string, int64> data = 2;
|
string nodeID = 2;
|
||||||
string NodeID = 3;
|
map<string, bytes> data = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StreamResponse{
|
message StreamResponse{
|
||||||
string type = 1;
|
string type = 1;
|
||||||
bytes profile = 2;
|
string nodeID = 2;
|
||||||
map<string, int64> data = 3;
|
bytes profile = 3;
|
||||||
string NodeID = 4;
|
bytes tasks = 4;
|
||||||
bytes tasks = 5;
|
map<string, bytes> data = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RegisterRequest{
|
message RegisterRequest{
|
||||||
string NodeID = 1;
|
string nodeID = 1;
|
||||||
|
string os = 2;
|
||||||
|
string arch = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RegisterResponse{
|
message RegisterResponse{
|
||||||
@@ -34,7 +36,7 @@ message RegisterResponse{
|
|||||||
}
|
}
|
||||||
|
|
||||||
message SignOutRequest{
|
message SignOutRequest{
|
||||||
string NodeID = 1;
|
string nodeID = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SignOutResponse{
|
message SignOutResponse{
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type genericMessage struct {
|
type genericMessage struct {
|
||||||
Type string `json:"type,omitempty"`
|
Type string `json:"type,omitempty"`
|
||||||
Profile []byte `json:"profile,omitempty"`
|
Profile []byte `json:"profile,omitempty"`
|
||||||
Data map[string]int64 `json:"data,omitempty"`
|
Data map[string][]byte `json:"data,omitempty"`
|
||||||
NodeID string `json:"node_id,omitempty"`
|
NodeID string `json:"node_id,omitempty"`
|
||||||
Tasks []byte `json:"tasks,omitempty"`
|
Tasks []byte `json:"tasks,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type task struct {
|
type task struct {
|
||||||
@@ -23,7 +23,7 @@ type task struct {
|
|||||||
TestCases []byte `json:"testcases,omitempty"`
|
TestCases []byte `json:"testcases,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGenericMessage(t string, data map[string]int64, nodeID string) (msg *genericMessage) {
|
func newGenericMessage(t string, data map[string][]byte, nodeID string) (msg *genericMessage) {
|
||||||
return &genericMessage{
|
return &genericMessage{
|
||||||
Type: t,
|
Type: t,
|
||||||
Data: data,
|
Data: data,
|
||||||
@@ -38,7 +38,7 @@ func newQuitMessage(nodeID string) (msg *genericMessage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMessageToWorker(t string, profile []byte, data map[string]int64, tasks []byte) (msg *genericMessage) {
|
func newMessageToWorker(t string, profile []byte, data map[string][]byte, tasks []byte) (msg *genericMessage) {
|
||||||
return &genericMessage{
|
return &genericMessage{
|
||||||
Type: t,
|
Type: t,
|
||||||
Profile: profile,
|
Profile: profile,
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ const (
|
|||||||
reportStatsInterval = 3 * time.Second
|
reportStatsInterval = 3 * time.Second
|
||||||
heartbeatInterval = 1 * time.Second
|
heartbeatInterval = 1 * time.Second
|
||||||
heartbeatLiveness = 3 * time.Second
|
heartbeatLiveness = 3 * time.Second
|
||||||
|
reconnectInterval = 3 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
type Loop struct {
|
type Loop struct {
|
||||||
@@ -392,10 +393,11 @@ func (r *runner) spawnWorkers(spawnCount int64, spawnRate float64, quit chan boo
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-quit:
|
case <-quit:
|
||||||
atomic.AddInt64(&r.controller.currentClientsNum, -1)
|
r.controller.increaseFinishedCount()
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
if workerLoop != nil && !workerLoop.acquire() {
|
if workerLoop != nil && !workerLoop.acquire() {
|
||||||
|
r.controller.increaseFinishedCount()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if r.rateLimitEnabled {
|
if r.rateLimitEnabled {
|
||||||
@@ -415,6 +417,8 @@ func (r *runner) spawnWorkers(spawnCount int64, spawnRate float64, quit chan boo
|
|||||||
workerLoop.increaseFinishedCount()
|
workerLoop.increaseFinishedCount()
|
||||||
if r.loop.isFinished() {
|
if r.loop.isFinished() {
|
||||||
go r.stop()
|
go r.stop()
|
||||||
|
r.controller.increaseFinishedCount()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if r.controller.erase() {
|
if r.controller.erase() {
|
||||||
@@ -621,7 +625,8 @@ func (r *localRunner) start() {
|
|||||||
go r.spawnWorkers(r.getSpawnCount(), r.getSpawnRate(), r.stoppingChan, nil)
|
go r.spawnWorkers(r.getSpawnCount(), r.getSpawnRate(), r.stoppingChan, nil)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
r.wgMu.Lock() // block concurrent waitgroup adds in GoAttach while stopping
|
// block concurrent waitgroup adds in GoAttach while stopping
|
||||||
|
r.wgMu.Lock()
|
||||||
r.updateState(StateStopping)
|
r.updateState(StateStopping)
|
||||||
close(r.stoppingChan)
|
close(r.stoppingChan)
|
||||||
close(r.rebalance)
|
close(r.rebalance)
|
||||||
@@ -634,10 +639,8 @@ func (r *localRunner) start() {
|
|||||||
|
|
||||||
// wait until all stats are reported successfully
|
// wait until all stats are reported successfully
|
||||||
<-r.reportedChan
|
<-r.reportedChan
|
||||||
|
|
||||||
// report test result
|
// report test result
|
||||||
r.reportTestResult()
|
r.reportTestResult()
|
||||||
|
|
||||||
// output teardown
|
// output teardown
|
||||||
r.outputOnStop()
|
r.outputOnStop()
|
||||||
|
|
||||||
@@ -693,8 +696,8 @@ func newWorkerRunner(masterHost string, masterPort int) (r *workerRunner) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *workerRunner) spawnComplete() {
|
func (r *workerRunner) spawnComplete() {
|
||||||
data := make(map[string]int64)
|
data := make(map[string][]byte)
|
||||||
data["count"] = r.controller.getSpawnCount()
|
data["count"] = builtin.Int64ToBytes(r.controller.getSpawnCount())
|
||||||
r.client.sendChannel() <- newGenericMessage("spawning_complete", data, r.nodeID)
|
r.client.sendChannel() <- newGenericMessage("spawning_complete", data, r.nodeID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -755,8 +758,6 @@ func (r *workerRunner) onMessage(msg *genericMessage) {
|
|||||||
r.onRebalanceMessage(msg)
|
r.onRebalanceMessage(msg)
|
||||||
case "stop":
|
case "stop":
|
||||||
r.stop()
|
r.stop()
|
||||||
log.Info().Msg("Recv stop message from master, all the goroutines are stopped")
|
|
||||||
r.client.sendChannel() <- newGenericMessage("client_stopped", nil, r.nodeID)
|
|
||||||
case "quit":
|
case "quit":
|
||||||
r.stop()
|
r.stop()
|
||||||
if r.ignoreQuit {
|
if r.ignoreQuit {
|
||||||
@@ -780,6 +781,10 @@ func (r *workerRunner) onMessage(msg *genericMessage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *workerRunner) onStopped() {
|
||||||
|
r.client.sendChannel() <- newGenericMessage("client_stopped", nil, r.nodeID)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *workerRunner) onQuiting() {
|
func (r *workerRunner) onQuiting() {
|
||||||
if r.getState() != StateQuitting {
|
if r.getState() != StateQuitting {
|
||||||
r.client.sendChannel() <- newQuitMessage(r.nodeID)
|
r.client.sendChannel() <- newQuitMessage(r.nodeID)
|
||||||
@@ -832,7 +837,7 @@ func (r *workerRunner) run() {
|
|||||||
select {
|
select {
|
||||||
case <-r.client.disconnectedChannel():
|
case <-r.client.disconnectedChannel():
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
log.Warn().Msg("Timeout waiting for sending quit message to master, boomer will quit any way.")
|
log.Warn().Msg("timeout waiting for sending quit message to master, boomer will quit any way.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign out from master
|
// sign out from master
|
||||||
@@ -858,25 +863,31 @@ func (r *workerRunner) run() {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
if atomic.LoadInt32(&r.client.failCount) > 2 {
|
|
||||||
r.updateState(StateMissing)
|
|
||||||
}
|
|
||||||
if r.getState() == StateMissing {
|
if r.getState() == StateMissing {
|
||||||
err = r.client.register(r.client.config.ctx)
|
err = r.client.register(r.client.config.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if r.client.newBiStreamClient() == nil {
|
err = r.client.newBiStreamClient()
|
||||||
r.updateState(StateInit)
|
if err != nil {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
r.updateState(StateInit)
|
||||||
}
|
}
|
||||||
CPUUsage := GetCurrentCPUUsage()
|
if atomic.LoadInt32(&r.client.failCount) > 2 {
|
||||||
MemoryUsage := GetCurrentMemoryUsage()
|
r.updateState(StateMissing)
|
||||||
data := map[string]int64{
|
}
|
||||||
"state": int64(r.getState()),
|
CPUUsage := GetCurrentCPUPercent()
|
||||||
"current_cpu_usage": int64(CPUUsage), // percentage
|
MemoryUsage := GetCurrentMemoryPercent()
|
||||||
"current_memory_usage": int64(MemoryUsage), // percentage
|
PidCPUUsage := GetCurrentPidCPUUsage()
|
||||||
"current_users": r.controller.getCurrentClientsNum(),
|
PidMemoryUsage := GetCurrentPidMemoryUsage()
|
||||||
|
data := map[string][]byte{
|
||||||
|
"state": builtin.Int64ToBytes(int64(r.getState())),
|
||||||
|
"current_cpu_usage": builtin.Float64ToByte(CPUUsage),
|
||||||
|
"current_pid_cpu_usage": builtin.Float64ToByte(PidCPUUsage),
|
||||||
|
"current_memory_usage": builtin.Float64ToByte(MemoryUsage),
|
||||||
|
"current_pid_memory_usage": builtin.Float64ToByte(PidMemoryUsage),
|
||||||
|
"current_users": builtin.Int64ToBytes(r.controller.getCurrentClientsNum()),
|
||||||
}
|
}
|
||||||
r.client.sendChannel() <- newGenericMessage("heartbeat", data, r.nodeID)
|
r.client.sendChannel() <- newGenericMessage("heartbeat", data, r.nodeID)
|
||||||
case <-r.closeChan:
|
case <-r.closeChan:
|
||||||
@@ -901,7 +912,8 @@ func (r *workerRunner) start() {
|
|||||||
go r.spawnWorkers(r.getSpawnCount(), r.getSpawnRate(), r.stoppingChan, r.spawnComplete)
|
go r.spawnWorkers(r.getSpawnCount(), r.getSpawnRate(), r.stoppingChan, r.spawnComplete)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
r.wgMu.Lock() // block concurrent waitgroup adds in GoAttach while stopping
|
// block concurrent waitgroup adds in GoAttach while stopping
|
||||||
|
r.wgMu.Lock()
|
||||||
r.updateState(StateStopping)
|
r.updateState(StateStopping)
|
||||||
close(r.stoppingChan)
|
close(r.stoppingChan)
|
||||||
close(r.rebalance)
|
close(r.rebalance)
|
||||||
@@ -912,9 +924,13 @@ func (r *workerRunner) start() {
|
|||||||
|
|
||||||
close(r.doneChan)
|
close(r.doneChan)
|
||||||
|
|
||||||
|
// notify master that worker is stopped
|
||||||
|
r.onStopped()
|
||||||
|
// wait until all stats are reported successfully
|
||||||
<-r.reportedChan
|
<-r.reportedChan
|
||||||
|
// report test result
|
||||||
r.reportTestResult()
|
r.reportTestResult()
|
||||||
|
// output teardown
|
||||||
r.outputOnStop()
|
r.outputOnStop()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -991,13 +1007,16 @@ func (r *masterRunner) heartbeatWorker() {
|
|||||||
if !ok {
|
if !ok {
|
||||||
log.Error().Msg("failed to get worker information")
|
log.Error().Msg("failed to get worker information")
|
||||||
}
|
}
|
||||||
if atomic.LoadInt32(&workerInfo.Heartbeat) <= 0 && workerInfo.getState() != StateMissing {
|
if atomic.LoadInt32(&workerInfo.Heartbeat) <= 0 {
|
||||||
workerInfo.setState(StateMissing)
|
if workerInfo.getState() != StateMissing {
|
||||||
|
workerInfo.setState(StateMissing)
|
||||||
|
}
|
||||||
if r.getState() == StateRunning {
|
if r.getState() == StateRunning {
|
||||||
// all running workers missed, stopping runner
|
// all running workers missed, stopping runner
|
||||||
if r.server.getClientsLength() <= 0 {
|
if r.server.getClientsLength() <= 0 {
|
||||||
r.updateState(StateStopped)
|
r.updateState(StateStopped)
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
atomic.AddInt32(&workerInfo.Heartbeat, -1)
|
atomic.AddInt32(&workerInfo.Heartbeat, -1)
|
||||||
@@ -1041,19 +1060,15 @@ func (r *masterRunner) clientListener() {
|
|||||||
r.updateState(StateStopped)
|
r.updateState(StateStopped)
|
||||||
}
|
}
|
||||||
case typeHeartbeat:
|
case typeHeartbeat:
|
||||||
if workerInfo.getState() != int32(msg.Data["state"]) {
|
if workerInfo.getState() != int32(builtin.BytesToInt64(msg.Data["state"])) {
|
||||||
workerInfo.setState(int32(msg.Data["state"]))
|
workerInfo.setState(int32(builtin.BytesToInt64(msg.Data["state"])))
|
||||||
}
|
}
|
||||||
workerInfo.updateHeartbeat(3)
|
workerInfo.updateHeartbeat(3)
|
||||||
if workerInfo.getCPUUsage() != float64(msg.Data["current_cpu_usage"]) {
|
workerInfo.updateCPUUsage(builtin.ByteToFloat64(msg.Data["current_cpu_usage"]))
|
||||||
workerInfo.updateCPUUsage(float64(msg.Data["current_cpu_usage"]))
|
workerInfo.updateWorkerCPUUsage(builtin.ByteToFloat64(msg.Data["current_pid_cpu_usage"]))
|
||||||
}
|
workerInfo.updateMemoryUsage(builtin.ByteToFloat64(msg.Data["current_memory_usage"]))
|
||||||
if workerInfo.getMemoryUsage() != float64(msg.Data["current_memory_usage"]) {
|
workerInfo.updateWorkerMemoryUsage(builtin.ByteToFloat64(msg.Data["current_pid_memory_usage"]))
|
||||||
workerInfo.updateMemoryUsage(float64(msg.Data["current_memory_usage"]))
|
workerInfo.updateUserCount(builtin.BytesToInt64(msg.Data["current_users"]))
|
||||||
}
|
|
||||||
if workerInfo.getSpawnCount() != msg.Data["current_users"] {
|
|
||||||
workerInfo.updateSpawnCount(msg.Data["current_users"])
|
|
||||||
}
|
|
||||||
case typeSpawning:
|
case typeSpawning:
|
||||||
workerInfo.setState(StateSpawning)
|
workerInfo.setState(StateSpawning)
|
||||||
case typeSpawningComplete:
|
case typeSpawningComplete:
|
||||||
@@ -1095,12 +1110,6 @@ func (r *masterRunner) run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
// disconnecting workers
|
|
||||||
close(r.server.disconnectedChan)
|
|
||||||
|
|
||||||
// waiting to close bidirectional stream
|
|
||||||
r.server.wg.Wait()
|
|
||||||
|
|
||||||
// close server
|
// close server
|
||||||
r.server.close()
|
r.server.close()
|
||||||
}()
|
}()
|
||||||
@@ -1191,7 +1200,6 @@ func (r *masterRunner) start() error {
|
|||||||
workerInfo.getStream() <- &messager.StreamResponse{
|
workerInfo.getStream() <- &messager.StreamResponse{
|
||||||
Type: "spawn",
|
Type: "spawn",
|
||||||
Profile: ProfileToBytes(workerProfile),
|
Profile: ProfileToBytes(workerProfile),
|
||||||
Data: map[string]int64{},
|
|
||||||
NodeID: workerInfo.ID,
|
NodeID: workerInfo.ID,
|
||||||
Tasks: testcase,
|
Tasks: testcase,
|
||||||
}
|
}
|
||||||
@@ -1245,7 +1253,6 @@ func (r *masterRunner) rebalance() error {
|
|||||||
workerInfo.getStream() <- &messager.StreamResponse{
|
workerInfo.getStream() <- &messager.StreamResponse{
|
||||||
Type: "spawn",
|
Type: "spawn",
|
||||||
Profile: ProfileToBytes(workerProfile),
|
Profile: ProfileToBytes(workerProfile),
|
||||||
Data: map[string]int64{},
|
|
||||||
NodeID: workerInfo.ID,
|
NodeID: workerInfo.ID,
|
||||||
Tasks: r.tcb,
|
Tasks: r.tcb,
|
||||||
}
|
}
|
||||||
@@ -1253,7 +1260,6 @@ func (r *masterRunner) rebalance() error {
|
|||||||
workerInfo.getStream() <- &messager.StreamResponse{
|
workerInfo.getStream() <- &messager.StreamResponse{
|
||||||
Type: "rebalance",
|
Type: "rebalance",
|
||||||
Profile: ProfileToBytes(workerProfile),
|
Profile: ProfileToBytes(workerProfile),
|
||||||
Data: map[string]int64{},
|
|
||||||
NodeID: workerInfo.ID,
|
NodeID: workerInfo.ID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1284,7 +1290,7 @@ func (r *masterRunner) fetchTestCase() ([]byte, error) {
|
|||||||
func (r *masterRunner) stop() error {
|
func (r *masterRunner) stop() error {
|
||||||
if r.isStarting() {
|
if r.isStarting() {
|
||||||
r.updateState(StateStopping)
|
r.updateState(StateStopping)
|
||||||
r.server.sendBroadcasts(&genericMessage{Type: "stop", Data: map[string]int64{}})
|
r.server.sendBroadcasts(&genericMessage{Type: "stop"})
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
return errors.New("already stopped")
|
return errors.New("already stopped")
|
||||||
@@ -1314,16 +1320,16 @@ func (r *masterRunner) reportStats() {
|
|||||||
table := tablewriter.NewWriter(os.Stdout)
|
table := tablewriter.NewWriter(os.Stdout)
|
||||||
table.SetColMinWidth(0, 20)
|
table.SetColMinWidth(0, 20)
|
||||||
table.SetColMinWidth(1, 10)
|
table.SetColMinWidth(1, 10)
|
||||||
table.SetHeader([]string{"Worker ID", "IP", "State", "Current Users", "CPU Usage (%)", "Memory Usage (%)"})
|
table.SetHeader([]string{"Worker ID", "IP", "State", "Current Users", "CPU (%)", "Memory (%)"})
|
||||||
|
|
||||||
for _, worker := range r.server.getAllWorkers() {
|
for _, worker := range r.server.getAllWorkers() {
|
||||||
row := make([]string, 6)
|
row := make([]string, 6)
|
||||||
row[0] = worker.ID
|
row[0] = worker.ID
|
||||||
row[1] = worker.IP
|
row[1] = worker.IP
|
||||||
row[2] = fmt.Sprintf("%v", getStateName(worker.getState()))
|
row[2] = fmt.Sprintf("%v", getStateName(worker.getState()))
|
||||||
row[3] = fmt.Sprintf("%v", worker.getSpawnCount())
|
row[3] = fmt.Sprintf("%v", worker.getUserCount())
|
||||||
row[4] = fmt.Sprintf("%v", worker.getCPUUsage())
|
row[4] = fmt.Sprintf("%.2f", worker.getCPUUsage())
|
||||||
row[5] = fmt.Sprintf("%v", worker.getMemoryUsage())
|
row[5] = fmt.Sprintf("%.2f", worker.getMemoryUsage())
|
||||||
table.Append(row)
|
table.Append(row)
|
||||||
}
|
}
|
||||||
table.Render()
|
table.Render()
|
||||||
|
|||||||
@@ -25,20 +25,24 @@ import (
|
|||||||
type WorkerNode struct {
|
type WorkerNode struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
|
OS string `json:"os"`
|
||||||
|
Arch string `json:"arch"`
|
||||||
State int32 `json:"state"`
|
State int32 `json:"state"`
|
||||||
Heartbeat int32 `json:"heartbeat"`
|
Heartbeat int32 `json:"heartbeat"`
|
||||||
SpawnCount int64 `json:"spawn_count"`
|
UserCount int64 `json:"user_count"`
|
||||||
|
WorkerCPUUsage float64 `json:"worker_cpu_usage"`
|
||||||
CPUUsage float64 `json:"cpu_usage"`
|
CPUUsage float64 `json:"cpu_usage"`
|
||||||
CPUWarningEmitted bool `json:"cpu_warning_emitted"`
|
CPUWarningEmitted bool `json:"cpu_warning_emitted"`
|
||||||
|
WorkerMemoryUsage float64 `json:"worker_memory_usage"`
|
||||||
MemoryUsage float64 `json:"memory_usage"`
|
MemoryUsage float64 `json:"memory_usage"`
|
||||||
stream chan *messager.StreamResponse
|
stream chan *messager.StreamResponse
|
||||||
mutex sync.RWMutex
|
mutex sync.RWMutex
|
||||||
disconnectedChan chan bool
|
disconnectedChan chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWorkerNode(id, ip string) *WorkerNode {
|
func newWorkerNode(id, ip, os, arch string) *WorkerNode {
|
||||||
stream := make(chan *messager.StreamResponse, 100)
|
stream := make(chan *messager.StreamResponse, 100)
|
||||||
return &WorkerNode{State: StateInit, ID: id, IP: ip, Heartbeat: 3, stream: stream, disconnectedChan: make(chan bool)}
|
return &WorkerNode{State: StateInit, ID: id, IP: ip, OS: os, Arch: arch, Heartbeat: 3, stream: stream, disconnectedChan: make(chan bool)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerNode) getState() int32 {
|
func (w *WorkerNode) getState() int32 {
|
||||||
@@ -57,12 +61,12 @@ func (w *WorkerNode) getHeartbeat() int32 {
|
|||||||
return atomic.LoadInt32(&w.Heartbeat)
|
return atomic.LoadInt32(&w.Heartbeat)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerNode) updateSpawnCount(spawnCount int64) {
|
func (w *WorkerNode) updateUserCount(spawnCount int64) {
|
||||||
atomic.StoreInt64(&w.SpawnCount, spawnCount)
|
atomic.StoreInt64(&w.UserCount, spawnCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerNode) getSpawnCount() int64 {
|
func (w *WorkerNode) getUserCount() int64 {
|
||||||
return atomic.LoadInt64(&w.SpawnCount)
|
return atomic.LoadInt64(&w.UserCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerNode) updateCPUUsage(cpuUsage float64) {
|
func (w *WorkerNode) updateCPUUsage(cpuUsage float64) {
|
||||||
@@ -77,6 +81,18 @@ func (w *WorkerNode) getCPUUsage() float64 {
|
|||||||
return w.CPUUsage
|
return w.CPUUsage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WorkerNode) updateWorkerCPUUsage(workerCPUUsage float64) {
|
||||||
|
w.mutex.Lock()
|
||||||
|
defer w.mutex.Unlock()
|
||||||
|
w.WorkerCPUUsage = workerCPUUsage
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorkerNode) getWorkerCPUUsage() float64 {
|
||||||
|
w.mutex.RLock()
|
||||||
|
defer w.mutex.RUnlock()
|
||||||
|
return w.WorkerCPUUsage
|
||||||
|
}
|
||||||
|
|
||||||
func (w *WorkerNode) updateCPUWarningEmitted(cpuWarningEmitted bool) {
|
func (w *WorkerNode) updateCPUWarningEmitted(cpuWarningEmitted bool) {
|
||||||
w.mutex.Lock()
|
w.mutex.Lock()
|
||||||
defer w.mutex.Unlock()
|
defer w.mutex.Unlock()
|
||||||
@@ -89,6 +105,18 @@ func (w *WorkerNode) getCPUWarningEmitted() bool {
|
|||||||
return w.CPUWarningEmitted
|
return w.CPUWarningEmitted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WorkerNode) updateWorkerMemoryUsage(workerMemoryUsage float64) {
|
||||||
|
w.mutex.Lock()
|
||||||
|
defer w.mutex.Unlock()
|
||||||
|
w.WorkerMemoryUsage = workerMemoryUsage
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorkerNode) getWorkerMemoryUsage() float64 {
|
||||||
|
w.mutex.RLock()
|
||||||
|
defer w.mutex.RUnlock()
|
||||||
|
return w.WorkerMemoryUsage
|
||||||
|
}
|
||||||
|
|
||||||
func (w *WorkerNode) updateMemoryUsage(memoryUsage float64) {
|
func (w *WorkerNode) updateMemoryUsage(memoryUsage float64) {
|
||||||
w.mutex.Lock()
|
w.mutex.Lock()
|
||||||
defer w.mutex.Unlock()
|
defer w.mutex.Unlock()
|
||||||
@@ -119,11 +147,15 @@ func (w *WorkerNode) getWorkerInfo() WorkerNode {
|
|||||||
return WorkerNode{
|
return WorkerNode{
|
||||||
ID: w.ID,
|
ID: w.ID,
|
||||||
IP: w.IP,
|
IP: w.IP,
|
||||||
|
OS: w.OS,
|
||||||
|
Arch: w.Arch,
|
||||||
State: w.getState(),
|
State: w.getState(),
|
||||||
Heartbeat: w.getHeartbeat(),
|
Heartbeat: w.getHeartbeat(),
|
||||||
SpawnCount: w.getSpawnCount(),
|
UserCount: w.getUserCount(),
|
||||||
|
WorkerCPUUsage: w.getWorkerCPUUsage(),
|
||||||
CPUUsage: w.getCPUUsage(),
|
CPUUsage: w.getCPUUsage(),
|
||||||
CPUWarningEmitted: w.getCPUWarningEmitted(),
|
CPUWarningEmitted: w.getCPUWarningEmitted(),
|
||||||
|
WorkerMemoryUsage: w.getWorkerMemoryUsage(),
|
||||||
MemoryUsage: w.getMemoryUsage(),
|
MemoryUsage: w.getMemoryUsage(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,7 +299,7 @@ func (s *grpcServer) Register(ctx context.Context, req *messager.RegisterRequest
|
|||||||
p, _ := peer.FromContext(ctx)
|
p, _ := peer.FromContext(ctx)
|
||||||
clientIp := strings.Split(p.Addr.String(), ":")[0]
|
clientIp := strings.Split(p.Addr.String(), ":")[0]
|
||||||
// store worker information
|
// store worker information
|
||||||
wn := newWorkerNode(req.NodeID, clientIp)
|
wn := newWorkerNode(req.NodeID, clientIp, req.Os, req.Arch)
|
||||||
s.clients.Store(req.NodeID, wn)
|
s.clients.Store(req.NodeID, wn)
|
||||||
log.Warn().Str("worker id", req.NodeID).Msg("worker joined")
|
log.Warn().Str("worker id", req.NodeID).Msg("worker joined")
|
||||||
return &messager.RegisterResponse{Code: "0", Message: "register successfully"}, nil
|
return &messager.RegisterResponse{Code: "0", Message: "register successfully"}, nil
|
||||||
@@ -415,6 +447,12 @@ func (s *grpcServer) close() {
|
|||||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
s.stopServer(ctx)
|
s.stopServer(ctx)
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
|
// disconnecting workers
|
||||||
|
close(s.disconnectedChan)
|
||||||
|
|
||||||
|
// waiting to close bidirectional stream
|
||||||
|
s.wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *grpcServer) recvChannel() chan *genericMessage {
|
func (s *grpcServer) recvChannel() chan *genericMessage {
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/shirou/gopsutil/cpu"
|
||||||
|
"github.com/shirou/gopsutil/mem"
|
||||||
"github.com/shirou/gopsutil/process"
|
"github.com/shirou/gopsutil/process"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -88,8 +90,8 @@ func getNodeID() (nodeID string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentCPUUsage get current CPU usage
|
// GetCurrentPidCPUUsage get current pid CPU usage
|
||||||
func GetCurrentCPUUsage() float64 {
|
func GetCurrentPidCPUUsage() float64 {
|
||||||
currentPid := os.Getpid()
|
currentPid := os.Getpid()
|
||||||
p, err := process.NewProcess(int32(currentPid))
|
p, err := process.NewProcess(int32(currentPid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -104,8 +106,8 @@ func GetCurrentCPUUsage() float64 {
|
|||||||
return percent
|
return percent
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentCPUPercent get the percentage of current cpu used
|
// GetCurrentPidCPUPercent get the percentage of current pid cpu used
|
||||||
func GetCurrentCPUPercent() float64 {
|
func GetCurrentPidCPUPercent() float64 {
|
||||||
currentPid := os.Getpid()
|
currentPid := os.Getpid()
|
||||||
p, err := process.NewProcess(int32(currentPid))
|
p, err := process.NewProcess(int32(currentPid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -120,8 +122,20 @@ func GetCurrentCPUPercent() float64 {
|
|||||||
return percent
|
return percent
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentMemoryUsage get current Memory usage
|
// GetCurrentCPUPercent get the percentage of current cpu used
|
||||||
func GetCurrentMemoryUsage() float64 {
|
func GetCurrentCPUPercent() float64 {
|
||||||
|
percent, _ := cpu.Percent(time.Second, false)
|
||||||
|
return percent[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCurrentMemoryPercent get the percentage of current memory used
|
||||||
|
func GetCurrentMemoryPercent() float64 {
|
||||||
|
memInfo, _ := mem.VirtualMemory()
|
||||||
|
return memInfo.UsedPercent
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCurrentPidMemoryUsage get current Memory usage
|
||||||
|
func GetCurrentPidMemoryUsage() float64 {
|
||||||
currentPid := os.Getpid()
|
currentPid := os.Getpid()
|
||||||
p, err := process.NewProcess(int32(currentPid))
|
p, err := process.NewProcess(int32(currentPid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ package builtin
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
builtinJSON "encoding/json"
|
builtinJSON "encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -505,6 +507,42 @@ func Bytes2File(data []byte, filename string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Float32ToByte(v float32) []byte {
|
||||||
|
bits := math.Float32bits(v)
|
||||||
|
bytes := make([]byte, 4)
|
||||||
|
binary.LittleEndian.PutUint32(bytes, bits)
|
||||||
|
return bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
func ByteToFloat32(v []byte) float32 {
|
||||||
|
bits := binary.LittleEndian.Uint32(v)
|
||||||
|
return math.Float32frombits(bits)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Float64ToByte(v float64) []byte {
|
||||||
|
bits := math.Float64bits(v)
|
||||||
|
bts := make([]byte, 8)
|
||||||
|
binary.LittleEndian.PutUint64(bts, bits)
|
||||||
|
return bts
|
||||||
|
}
|
||||||
|
|
||||||
|
func ByteToFloat64(v []byte) float64 {
|
||||||
|
bits := binary.LittleEndian.Uint64(v)
|
||||||
|
return math.Float64frombits(bits)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Int64ToBytes(n int64) []byte {
|
||||||
|
bytesBuf := bytes.NewBuffer([]byte{})
|
||||||
|
_ = binary.Write(bytesBuf, binary.BigEndian, n)
|
||||||
|
return bytesBuf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BytesToInt64(bys []byte) (data int64) {
|
||||||
|
byteBuff := bytes.NewBuffer(bys)
|
||||||
|
_ = binary.Read(byteBuff, binary.BigEndian, &data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func SplitInteger(m, n int) (ints []int) {
|
func SplitInteger(m, n int) (ints []int) {
|
||||||
quotient := m / n
|
quotient := m / n
|
||||||
remainder := m % n
|
remainder := m % n
|
||||||
|
|||||||
Reference in New Issue
Block a user