you have to receive before you can send
V-inz opened this issue · 3 comments
working on o3demo issue #7 I found a more basic error:
You have to receive (pending offline-messages) before you can send!
What I did:
- I copied two instances of the o3demo: o3demo1 and o3demo2. I removed the auto-answer and copied four initial messages.
- Starting them and sending the initial messages to a third party works fine.
- Starting them and sending to each other, with starting o3demo2 about 5 sec later will block o3demo2 while sending its first initial message.
- o3demo2 will not work anymore (restart, ...), until you generate a new Threema-ID. This is, what kolAflash did here: o3demo issue #7. Thus the pending offline-messages from o3demo1 "killed" o3demo2.
- Now I stopped o3demo1 and sent four offline-messages from third party to o3demo1. Restarting o3demo1, I can see o3demo1 is "dead" too.
Kind of "solve":
- Ichanged o3demo1 and o3demo2 to not send the initial messages but do the receive.
- Both receive just the latest offline-message in their pipe and work again as they did from start.
So I draw the conclusion, you have to receive all pending offline-messages before you can send your first message.
I did not try to find, whether this block comes from Threema servers or from the o3ma/o3-lib.
I'd expect the o3ma/o3-lib because Threema servers should not delete all pending offline-messages except the latest, only because I tried to send.
(Maybe this is dependent on some timing during startup of the demo. So maybe you can see it on one computer but not the other. I saw it on a Raspberry Pi 2 but not on my desktop.)
I tried to verify this by first starting the receive-loop in background (see below) and after a delay sending messages.
To be honest, I have to admit that this does not help.
Next presumption would be, there are problems receiving messages in rapid succession.
// handle incoming messages
c := make(chan error, 1)
go func() { // background rcv-loop
fmt.Println("handle incoming messages")
for receivedMessage := range receiveMsgChan {
...
}
c<-nil
}()
time.Sleep(2000 * time.Millisecond)
// send our initial message to our recipient
for i := 1; i <= 4; i++ {
txt := fmt.Sprintf("Initial message %d from o3demo1", i)
fmt.Printf("%s to [%s]\n", txt, rid)
err = ctx.SendTextMessage(rid, txt, sendMsgChan)
if err != nil {
log.Fatal(err)
}
}
<-c // Wait for receivedMessage-Loop to exit
I think I need some help :)
Again I start a client with 4 pending offline-messages on the threema-servers.
In communicationhandler.go
inside func (sc *SessionContext) receiveLoop()
section case messagePacket:
a correct new message is received and pumped into the sc.receiveMsgChan
.
I can see the text of the message, when I put fmt.Printf("\nreceiveLoop: messagePacket: [[%v]]\n", rmsg.Msg)
right in front of it.
But in the o3demo, where the same channel is polled via for receivedMessage := range receiveMsgChan
, there is an event only for the first offline-message.
The second message is pushed into the channel, I can see it, but never comes out of it.
And now the receiving and sending is blocked.
I can't understand this, because (I think) I do not understand golang channels correctly.
P.S:
I can make things work, when a change receiveMsgChan to a Buffered Channel of not too small size. 500 works. But I think this is not a solution, because messages should no be received faster than they can be worked off.
You were right with your assessment about buffered channels. We should (and wanted to, if I remember correctly) have done that from the beginning. I added buffered channels in 3d612b6. We'll have to find a more scalable solution in the long run but this should fix the error in question and will allow you to use the demo as is.