From e5d2ffd3f9bf81a5fc4b1287ae8fb45a8763faa4 Mon Sep 17 00:00:00 2001 From: Aleksandr Zelenin Date: Fri, 31 Dec 2021 22:03:50 +0300 Subject: [PATCH] multi-instance fix --- client/client.go | 28 +++++++++++++++++++++++++--- client/tdlib.go | 6 +----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/client/client.go b/client/client.go index 8df2edd..325ad2f 100644 --- a/client/client.go +++ b/client/client.go @@ -3,10 +3,14 @@ package client import ( "context" "errors" + "log" "sync" + "sync/atomic" "time" ) +var clients = &sync.Map{} + type Client struct { jsonClient *JsonClient extraGenerator ExtraGenerator @@ -59,6 +63,8 @@ func NewClient(authorizationStateHandler AuthorizationStateHandler, options ...O catchersStore: &sync.Map{}, } + clients.Store(client.jsonClient.id, client) + client.extraGenerator = UuidV4Generator() client.catchTimeout = 60 * time.Second client.updatesTimeout = 60 * time.Second @@ -67,7 +73,7 @@ func NewClient(authorizationStateHandler AuthorizationStateHandler, options ...O option(client) } - go client.receive() + go receive(client) go client.catch(catchersListener) err := Authorize(client, authorizationStateHandler) @@ -78,12 +84,28 @@ func NewClient(authorizationStateHandler AuthorizationStateHandler, options ...O return client, nil } -func (client *Client) receive() { +var alreadyRunning uint32 + +func receive(client *Client) { + if atomic.LoadUint32(&alreadyRunning) != 0 { + return + } + atomic.StoreUint32(&alreadyRunning, 1) + for { - resp, err := client.jsonClient.Receive(client.updatesTimeout) + resp, err := Receive(client.updatesTimeout) if err != nil { continue } + + value, ok := clients.Load(resp.ClientId) + if !ok { + log.Printf("Response with wrong clientId: %d", resp.ClientId) + continue + } + + client := value.(*Client) + client.catcher <- resp typ, err := UnmarshalType(resp.Data) diff --git a/client/tdlib.go b/client/tdlib.go index bbc12bb..190c6f2 100644 --- a/client/tdlib.go +++ b/client/tdlib.go @@ -39,7 +39,7 @@ func (jsonClient *JsonClient) Send(req Request) { // shouldn't be called simultaneously from two different threads. // Returned pointer will be deallocated by TDLib during next call to td_json_client_receive or td_json_client_execute // in the same thread, so it can't be used after that. -func (jsonClient *JsonClient) Receive(timeout time.Duration) (*Response, error) { +func Receive(timeout time.Duration) (*Response, error) { result := C.td_receive(C.double(float64(timeout) / float64(time.Second))) if result == nil { return nil, errors.New("update receiving timeout") @@ -54,10 +54,6 @@ func (jsonClient *JsonClient) Receive(timeout time.Duration) (*Response, error) return nil, err } - if resp.ClientId != jsonClient.id { - return nil, errors.New("wrong @client_id") - } - resp.Data = data return &resp, nil