Closed FunkyYang closed 10 months ago
You need to check TDLib logs with verbosity level at least 3. Likely, the updates are sent and the issue is somewhere in the wrapper or handling of the updates.
d stderr.log this is my logit seems normal
TDLib works correctly, but the log contains no calls to td_receive
, which means that the app stopped to fetch updates and request responses. This may be caused by thread that call td_receive
being blocked and synchronously waiting for something.
so how can I fixed?
You need to find, why the app doesn't try to receive updates anymore. For example, find what blocks the thread, or forces it to terminate.
func (instance *tdlib) addClient(client *Client) {
instance.mu.Lock()
defer instance.mu.Unlock()
instance.clients[client.jsonClient.id] = client
instance.once.Do(func() {
go instance.receiver()
})
}
func (instance *tdlib) receiver() {
for {
resp, err := instance.receive(instance.timeout)
if err != nil {
continue
}
client, err := instance.getClient(resp.ClientId)
if err != nil {
log.Print(err)
continue
}
client.responses <- resp
}
}
it could have
// Receives incoming updates and request responses from the TDLib client. May be called from any thread, but
// 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 (instance *tdlib) 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")
}
data := []byte(C.GoString(result))
var resp Response
err := json.Unmarshal(data, &resp)
if err != nil {
return nil, err
}
resp.Data = data
return &resp, nil
}
Do you use multiple TDLib instances simultaneously?
No I write messages to many groups and collect them reply one by one
use one account
Then, you need to find, why the app doesn't try to receive updates anymore. For example, find what blocks the thread processing updates, or forces it to terminate.
If the thread is blocked by a mutex, you will see no activity in the thread.
I use pprof to monitor the program and which metric should I notice?
You must check stack trace of the receiver thread to find what it does.
how can I do that?
You need to use a debugger for this.
func (instance *tdlib) receiver() {
for {
resp, err := instance.receive(instance.timeout)
if err != nil {
log.Print(err)
continue
}
log.Printf("clientId:%d", resp.ClientId)
client, err := instance.getClient(resp.ClientId)
if err != nil {
log.Print(err)
continue
}
client.responses <- resp
}
}
func (instance *tdlib) 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")
}
data := []byte(C.GoString(result))
var resp Response
err := json.Unmarshal(data, &resp)
if err != nil {
return nil, err
}
resp.Data = data
return &resp, nil
}
result := C.td_receive(C.double(float64(timeout) / float64(time.Second)))
if result == nil {
return nil, errors.New("update receiving timeout")
}
// Receive Receives incoming updates and request responses from the TDLib client.
// You can provide string or UpdateData.
func (client *Client) Receive(timeout float64) []byte {
result := C.td_json_client_receive(client.Client, C.double(timeout))
return []byte(C.GoString(result))
}
difference between old and new
/**
* Receives incoming updates and request responses. Must not be called simultaneously from two different threads.
* The returned pointer can be used until the next call to td_receive or td_execute, after which it will be deallocated by TDLib.
* \param[in] timeout The maximum number of seconds allowed for this function to wait for new data.
* \return JSON-serialized null-terminated incoming update or request response. May be NULL if the timeout expires.
*/
TDJSON_EXPORT const char *td_receive(double timeout);
this could be a tdlib issue
@levlam
result := C.td_receive(C.double(float64(timeout) / float64(time.Second)))
will being blocked
Can I use
const char * [td_json_client_receive](https://core.telegram.org/tdlib/docs/td__json__client_8h.html#a9e0cb36bfa2bc2249905aebd7d07a4ac) (void *client, double timeout)
this could be a tdlib issue
This can't be a TDLib issue.
Can I use
td_json_client_receive
The new interface with td_receive
is better to use.
result := C.td_receive(C.double(float64(timeout) / float64(time.Second))) will being blocked?
Yes, blocked waiting for updates and request responses from TDLib. The function isn't called.
but them in a for loop which can't be break
anyhing else will be blocked can make this blocking?
the channel is fulled
I wonder why
the code above which I use come from go-tdlib (https://github.com/zelenin/go-tdlib) and running some time,the receive channel will be plug up and I write a message in telegram manual and no response will be print in my program.I have no idea about that? can be fixed?