ing
This commit is contained in:
commit
3fa82a3656
68
.gitignore
vendored
Normal file
68
.gitignore
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
### JetBrains template
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff:
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/dictionaries
|
||||||
|
|
||||||
|
# Sensitive or high-churn files:
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.xml
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
|
||||||
|
# Gradle:
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Mongo Explorer plugin:
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
## File-based project format:
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
## Plugin-specific files:
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
### Go template
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, build with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||||
|
.glide/
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
vendor/
|
||||||
|
glide.lock
|
||||||
|
.DS_Store
|
||||||
|
dist/
|
||||||
|
debug
|
32
.vscode/launch.json
vendored
Normal file
32
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Debug",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "debug",
|
||||||
|
"remotePath": "",
|
||||||
|
"port": 2345,
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"program": "${workspaceRoot}/main.go",
|
||||||
|
"env": {},
|
||||||
|
"args": [],
|
||||||
|
"showLog": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "File Debug",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "debug",
|
||||||
|
"remotePath": "",
|
||||||
|
"port": 2345,
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"program": "${fileDirname}",
|
||||||
|
"env": {},
|
||||||
|
"args": [],
|
||||||
|
"showLog": true
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
// Place your settings in this file to overwrite default and user settings.
|
||||||
|
{
|
||||||
|
}
|
5
glide.yaml
Normal file
5
glide.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package: git.loafle.net/prototype/ipc
|
||||||
|
import:
|
||||||
|
- package: git.loafle.net/commons_go/rpc
|
||||||
|
- package: git.loafle.net/commons_go/server
|
||||||
|
- package: git.loafle.net/overflow/overflow_discovery
|
27
logging.json
Normal file
27
logging.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"level": "debug",
|
||||||
|
"development": true,
|
||||||
|
"disableCaller": true,
|
||||||
|
"disableStacktrace": true,
|
||||||
|
"sampling": {
|
||||||
|
"initial": 100,
|
||||||
|
"thereafter": 100
|
||||||
|
},
|
||||||
|
"encoding": "console",
|
||||||
|
"encoderConfig": {
|
||||||
|
"messageKey": "message",
|
||||||
|
"levelKey": "level",
|
||||||
|
"timeKey": "time",
|
||||||
|
"nameKey": "name",
|
||||||
|
"callerKey": "caller",
|
||||||
|
"stacktraceKey": "stacktrace",
|
||||||
|
"lineEnding": "\n",
|
||||||
|
"levelEncoder": "color",
|
||||||
|
"timeEncoder": "ISO8601",
|
||||||
|
"durationEncoder": "string",
|
||||||
|
"callerEncoder": "full",
|
||||||
|
"nameEncoder": "full"
|
||||||
|
},
|
||||||
|
"outputPaths": ["stdout", "/tmp/logs1"],
|
||||||
|
"errorOutputPaths": ["stderr"]
|
||||||
|
}
|
358
main.go
Normal file
358
main.go
Normal file
|
@ -0,0 +1,358 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
cRPC "git.loafle.net/commons_go/rpc"
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/client"
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
registry := cRPC.NewRegistry()
|
||||||
|
registry.RegisterService(new(rpc.DiscoveryService), "")
|
||||||
|
|
||||||
|
c := client.New("/tmp/discovery.sock", registry)
|
||||||
|
if err := c.Connect(); nil != err {
|
||||||
|
fmt.Printf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// reqParam := rpc.StartRequestParam{}
|
||||||
|
// resParam := rpc.StartResponseParam{}
|
||||||
|
|
||||||
|
// for index := 0; index < 10; index++ {
|
||||||
|
// reqParam.Count = index
|
||||||
|
// reqParam.Name = fmt.Sprintf("IPC %d", index)
|
||||||
|
|
||||||
|
// if err := c.Call("DiscoveryService.Start", &reqParam, &resParam); nil != err {
|
||||||
|
// fmt.Printf("%v\n", err)
|
||||||
|
// } else {
|
||||||
|
// fmt.Printf("%v\n", resParam)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// reqParamCS := rpc.StartRequestParam{Count: 1, Name: fmt.Sprintf("Start %d", 1)}
|
||||||
|
// resParamCS := rpc.StartResponseParam{}
|
||||||
|
|
||||||
|
// if err := c.Call(&resParamCS, "DiscoveryService.Start", &reqParamCS); nil != err {
|
||||||
|
// fmt.Printf("%v\n", err)
|
||||||
|
// } else {
|
||||||
|
// fmt.Printf("%v\n", resParamCS)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// reqParamCD := rpc.StartRequestParam{Count: 1, Name: fmt.Sprintf("Discovery %d", 1)}
|
||||||
|
// if err := c.Call(nil, "DiscoveryService.Discovery", "CallDiscovery", &reqParamCD); nil != err {
|
||||||
|
// fmt.Printf("%v\n", err)
|
||||||
|
// } else {
|
||||||
|
// fmt.Printf("DiscoveryService.Discovery end\n")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// reqParamCD1 := rpc.StartRequestParam{Count: 1, Name: fmt.Sprintf("Discovery1 %d", 1)}
|
||||||
|
// if err := c.Call(nil, "DiscoveryService.Discovery1", 3000, "CallDiscovery1", &reqParamCD1); nil != err {
|
||||||
|
// fmt.Printf("%v\n", err)
|
||||||
|
// } else {
|
||||||
|
// fmt.Printf("DiscoveryService.Discovery1 end\n")
|
||||||
|
// }
|
||||||
|
|
||||||
|
reqParamCD2 := rpc.StartRequestParam{Count: 1, Name: fmt.Sprintf("Discovery2-%d", 1)}
|
||||||
|
resParamCD2 := rpc.StartResponseParam{}
|
||||||
|
if err := c.Call(&resParamCD2, "DiscoveryService.Discovery2", 3000, "CallDiscovery1", &reqParamCD2); nil != err {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("DiscoveryService.Discovery2: %v\n", resParamCD2)
|
||||||
|
}
|
||||||
|
|
||||||
|
reqParamCD3 := rpc.StartRequestParam{Count: 1, Name: fmt.Sprintf("Discovery3-%d", 1)}
|
||||||
|
resParamCD3 := rpc.StartResponseParam{}
|
||||||
|
if err := c.Call(&resParamCD3, "DiscoveryService.Discovery3", []string{"CallDiscovery1", "CallDiscovery2"}, &reqParamCD3); nil != err {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("DiscoveryService.Discovery3: %v\n", resParamCD3)
|
||||||
|
}
|
||||||
|
|
||||||
|
reqParamCD4 := rpc.StartRequestParam{Count: 1, Name: fmt.Sprintf("Discovery4-%d", 1)}
|
||||||
|
resParamCD4 := rpc.StartResponseParam{}
|
||||||
|
if err := c.Call(&resParamCD4, "DiscoveryService.Discovery4", map[string]string{"CallDiscovery1": "1111", "CallDiscovery2": "3423423"}, &reqParamCD4); nil != err {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("DiscoveryService.Discovery4: %v\n", resParamCD4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// for index := 0; index < 10; index++ {
|
||||||
|
// reqParam.Count = index
|
||||||
|
// reqParam.Name = fmt.Sprintf("IPC %d", index)
|
||||||
|
|
||||||
|
// if err := c.Notify("DiscoveryService.Start", &reqParam); nil != err {
|
||||||
|
// fmt.Printf("%v\n", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// reqParam := rpc.StartRequestParam{Name: "Notify10", Count: 10000}
|
||||||
|
// if err := c.Notify("DiscoveryService.Start", &reqParam); nil != err {
|
||||||
|
// fmt.Printf("%v\n", err)
|
||||||
|
// }
|
||||||
|
// reqParamNS := rpc.StartRequestParam{Name: "NotifyStart", Count: 1000}
|
||||||
|
// if err := c.Notify("DiscoveryService.Discovery", "NotifyStart", &reqParamNS); nil != err {
|
||||||
|
// fmt.Printf("%v\n", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// reqParamND := rpc.StartRequestParam{Name: "Notify11", Count: 1000}
|
||||||
|
// if err := c.Notify("DiscoveryService.Discovery", "NotifyDiscovery", &reqParamND); nil != err {
|
||||||
|
// fmt.Printf("%v\n", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// time.Sleep(10 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
// type Param struct {
|
||||||
|
// Name string
|
||||||
|
// Count int
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func main() {
|
||||||
|
// param := &Param{Name: "393493", Count: 10}
|
||||||
|
// marshal("Discovery.Service", "Args", 100, param)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func marshal(name string, params ...interface{}) {
|
||||||
|
// buf, err := json.Marshal(params)
|
||||||
|
// if nil != err {
|
||||||
|
// log.Printf("%v\n", err)
|
||||||
|
// } else {
|
||||||
|
// log.Printf("%s\n", string(buf))
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var p []interface{}
|
||||||
|
|
||||||
|
// err = json.Unmarshal(buf, &p)
|
||||||
|
// if nil != err {
|
||||||
|
// log.Printf("%v\n", err)
|
||||||
|
// } else {
|
||||||
|
// log.Printf("%v\n", p)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type service struct {
|
||||||
|
// name string // name of service
|
||||||
|
// rcvrV reflect.Value // receiver of methods for the service
|
||||||
|
// rcvrT reflect.Type // type of the receiver
|
||||||
|
// methods map[string]*serviceMethod // registered methods
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type serviceMethod struct {
|
||||||
|
// method reflect.Method // receiver method
|
||||||
|
// paramTypes []reflect.Type // type of the request argument
|
||||||
|
// paramValues []reflect.Value
|
||||||
|
// returnType reflect.Type // type of the response argument
|
||||||
|
// returnValue reflect.Value
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type serviceMap struct {
|
||||||
|
// mutex sync.Mutex
|
||||||
|
// services map[string]*service
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (m *serviceMap) register(s interface{}, name string) error {
|
||||||
|
// st := reflect.TypeOf(s)
|
||||||
|
// sv := reflect.ValueOf(s)
|
||||||
|
// sName := reflect.Indirect(sv).Type().Name()
|
||||||
|
|
||||||
|
// sMap := &service{
|
||||||
|
// name: sName,
|
||||||
|
// rcvrV: sv,
|
||||||
|
// rcvrT: st,
|
||||||
|
// methods: make(map[string]*serviceMethod),
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for i := 0; i < st.NumMethod(); i++ {
|
||||||
|
// m := st.Method(i)
|
||||||
|
// mt := m.Type
|
||||||
|
|
||||||
|
// var paramTypes []reflect.Type
|
||||||
|
// var paramValues []reflect.Value
|
||||||
|
// var returnType reflect.Type
|
||||||
|
// var returnValue reflect.Value
|
||||||
|
|
||||||
|
// pCount := mt.NumIn() - 1
|
||||||
|
// log.Printf("Parameter count of Method[%s.%s] is %d.\n", sName, m.Name, pCount)
|
||||||
|
|
||||||
|
// if 0 < pCount {
|
||||||
|
// paramTypes = make([]reflect.Type, pCount)
|
||||||
|
// paramValues = make([]reflect.Value, pCount)
|
||||||
|
|
||||||
|
// for indexI := 0; indexI < pCount; indexI++ {
|
||||||
|
// pt := mt.In(indexI + 1)
|
||||||
|
// if pt.Kind() == reflect.Struct {
|
||||||
|
// log.Printf("Param[%d] of Method[%s.%s] is Struct type.\n", indexI, sName, m.Name)
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// if pt.Kind() == reflect.Ptr {
|
||||||
|
// paramTypes[indexI] = pt.Elem()
|
||||||
|
// } else {
|
||||||
|
// paramTypes[indexI] = pt
|
||||||
|
// }
|
||||||
|
// log.Printf("Param[%d] Type[%v] of Method[%s.%s] is Struct type.\n", indexI, paramTypes[indexI], sName, m.Name)
|
||||||
|
// pv := reflect.New(paramTypes[indexI])
|
||||||
|
// if paramValues[indexI].Kind() != reflect.Struct {
|
||||||
|
// paramValues[indexI] = reflect.Indirect(pv)
|
||||||
|
// } else {
|
||||||
|
// paramValues[indexI] = pv
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if 0 < mt.NumOut() {
|
||||||
|
// rt := mt.Out(0)
|
||||||
|
// if rt.Kind() == reflect.Struct {
|
||||||
|
// log.Printf("Return of Method[%s.%s] is Struct type.\n", sName, m.Name)
|
||||||
|
// }
|
||||||
|
// if rt.Kind() == reflect.Ptr {
|
||||||
|
// returnType = rt.Elem()
|
||||||
|
// } else {
|
||||||
|
// returnType = rt
|
||||||
|
// }
|
||||||
|
// rv := reflect.New(returnType)
|
||||||
|
// if returnType.Kind() != reflect.Struct {
|
||||||
|
// returnValue = reflect.Indirect(rv)
|
||||||
|
// } else {
|
||||||
|
// returnValue = rv
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// sMap.methods[m.Name] = &serviceMethod{
|
||||||
|
// method: m,
|
||||||
|
// paramTypes: paramTypes,
|
||||||
|
// paramValues: paramValues,
|
||||||
|
// returnType: returnType,
|
||||||
|
// returnValue: returnValue,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// m.mutex.Lock()
|
||||||
|
// defer m.mutex.Unlock()
|
||||||
|
// if m.services == nil {
|
||||||
|
// m.services = make(map[string]*service)
|
||||||
|
// } else if _, ok := m.services[sMap.name]; ok {
|
||||||
|
// return fmt.Errorf("rpc: service already defined: %q", sMap.name)
|
||||||
|
// }
|
||||||
|
// m.services[sMap.name] = sMap
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (m *serviceMap) get(method string) (*service, *serviceMethod, error) {
|
||||||
|
// parts := strings.Split(method, ".")
|
||||||
|
// if len(parts) != 2 {
|
||||||
|
// err := fmt.Errorf("rpc: service/method request ill-formed: %q", method)
|
||||||
|
// return nil, nil, err
|
||||||
|
// }
|
||||||
|
// m.mutex.Lock()
|
||||||
|
// service := m.services[parts[0]]
|
||||||
|
// m.mutex.Unlock()
|
||||||
|
// if service == nil {
|
||||||
|
// err := fmt.Errorf("rpc: can't find service %q", method)
|
||||||
|
// return nil, nil, err
|
||||||
|
// }
|
||||||
|
// serviceMethod := service.methods[parts[1]]
|
||||||
|
// if serviceMethod == nil {
|
||||||
|
// err := fmt.Errorf("rpc: can't find method %q", method)
|
||||||
|
// return nil, nil, err
|
||||||
|
// }
|
||||||
|
// return service, serviceMethod, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func main() {
|
||||||
|
// sMap := &serviceMap{}
|
||||||
|
|
||||||
|
// st := &ServiceTest{}
|
||||||
|
// if err := sMap.register(st, ""); nil != err {
|
||||||
|
// log.Printf("register: %v", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// s, m, err := sMap.get("ServiceTest.Start")
|
||||||
|
// if nil != err {
|
||||||
|
// log.Printf("register: %v", err)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// in := make([]reflect.Value, len(m.paramValues)+1)
|
||||||
|
// in[0] = s.rcvrV
|
||||||
|
// for indexI := 0; indexI < len(m.paramValues); indexI++ {
|
||||||
|
// in[indexI+1] = m.paramValues[indexI]
|
||||||
|
// //log.Printf("t: %v", m.paramTypes[indexI])
|
||||||
|
// //in[indexI+1].SetString("dddd")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// returnValues := m.method.Func.Call(in)
|
||||||
|
// log.Printf("returnValues: %v", returnValues)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type Param struct {
|
||||||
|
// Name string
|
||||||
|
// Count int
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type ServiceTest struct {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (s *ServiceTest) Start(name string) {
|
||||||
|
// log.Printf("ServiceTest.Start: %s", name)
|
||||||
|
// }
|
||||||
|
// func (s *ServiceTest) Start1(name string, count int) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// func (s *ServiceTest) Start2(p *Param) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// func (s *ServiceTest) Start3(name string, p *Param) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// import (
|
||||||
|
// "fmt"
|
||||||
|
// "reflect"
|
||||||
|
// )
|
||||||
|
|
||||||
|
// type Aaa struct {
|
||||||
|
// a string
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type Bbb struct {
|
||||||
|
// b int
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type Handler struct{}
|
||||||
|
|
||||||
|
// func (h Handler) GET(ss string, a Aaa, b Bbb, ptr *Aaa) string {
|
||||||
|
// return ss + "OK" + a.a + " ptr:" + ptr.a
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func main() {
|
||||||
|
// handler := new(Handler)
|
||||||
|
|
||||||
|
// objects := make(map[reflect.Type]interface{})
|
||||||
|
// objects[reflect.TypeOf(Aaa{})] = Aaa{"jkljkL"}
|
||||||
|
// objects[reflect.TypeOf(new(Aaa))] = &Aaa{"pointer!"}
|
||||||
|
// objects[reflect.TypeOf(Bbb{})] = Bbb{}
|
||||||
|
// objects[reflect.TypeOf("")] = "TestString"
|
||||||
|
|
||||||
|
// //in := make([]reflect.Value, 0)
|
||||||
|
// method := reflect.ValueOf(handler).MethodByName("GET")
|
||||||
|
|
||||||
|
// fmt.Println(method)
|
||||||
|
|
||||||
|
// in := make([]reflect.Value, method.Type().NumIn())
|
||||||
|
|
||||||
|
// fmt.Println("method type num in:", method.Type().NumIn())
|
||||||
|
// for i := 0; i < method.Type().NumIn(); i++ {
|
||||||
|
// t := method.Type().In(i)
|
||||||
|
// object := objects[t]
|
||||||
|
// fmt.Println(i, "->", object)
|
||||||
|
// in[i] = reflect.ValueOf(object)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fmt.Println("method type num out:", method.Type().NumOut())
|
||||||
|
|
||||||
|
// response := method.Call(in)
|
||||||
|
// fmt.Println(response)
|
||||||
|
// }
|
Loading…
Reference in New Issue
Block a user