Allow SendMessageToGroups to silently retry prior to failing
This commit is contained in:
parent
b2646d0f8e
commit
0f71da3fb6
|
@ -160,7 +160,7 @@ func (e *engine) eventHandler() {
|
||||||
case event.SendMessageToGroup:
|
case event.SendMessageToGroup:
|
||||||
ciphertext, _ := base64.StdEncoding.DecodeString(ev.Data[event.Ciphertext])
|
ciphertext, _ := base64.StdEncoding.DecodeString(ev.Data[event.Ciphertext])
|
||||||
signature, _ := base64.StdEncoding.DecodeString(ev.Data[event.Signature])
|
signature, _ := base64.StdEncoding.DecodeString(ev.Data[event.Signature])
|
||||||
go e.sendMessageToGroup(ev.Data[event.GroupID], ev.Data[event.GroupServer], ciphertext, signature)
|
go e.sendMessageToGroup(ev.Data[event.GroupID], ev.Data[event.GroupServer], ciphertext, signature, 0)
|
||||||
case event.SendMessageToPeer:
|
case event.SendMessageToPeer:
|
||||||
// TODO: remove this passthrough once the UI is integrated.
|
// TODO: remove this passthrough once the UI is integrated.
|
||||||
context, ok := ev.Data[event.EventContext]
|
context, ok := ev.Data[event.EventContext]
|
||||||
|
@ -480,7 +480,17 @@ func (e *engine) receiveGroupMessage(server string, gm *groups.EncryptedGroupMes
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendMessageToGroup attempts to sent the given message to the given group id.
|
// sendMessageToGroup attempts to sent the given message to the given group id.
|
||||||
func (e *engine) sendMessageToGroup(groupID string, server string, ct []byte, sig []byte) {
|
func (e *engine) sendMessageToGroup(groupID string, server string, ct []byte, sig []byte, attempts int) {
|
||||||
|
|
||||||
|
// sending to groups can fail for a few reasons (slow server, not enough tokens, etc.)
|
||||||
|
// rather than trying to keep all that logic in method we simply back-off and try again
|
||||||
|
// but if we fail more than 5 times then we report back to the client so they can investigate other options.
|
||||||
|
// Note: This flow only applies to online-and-connected servers (this method will return faster if the server is not
|
||||||
|
// online)
|
||||||
|
if attempts >= 5 {
|
||||||
|
e.eventManager.Publish(event.NewEvent(event.SendMessageToGroupError, map[event.Field]string{event.GroupID: groupID, event.GroupServer: server, event.Error: "could not make payment to server", event.Signature: base64.StdEncoding.EncodeToString(sig)}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
es, ok := e.ephemeralServices.Load(server)
|
es, ok := e.ephemeralServices.Load(server)
|
||||||
if es == nil || !ok {
|
if es == nil || !ok {
|
||||||
|
@ -493,17 +503,16 @@ func (e *engine) sendMessageToGroup(groupID string, server string, ct []byte, si
|
||||||
if err == nil {
|
if err == nil {
|
||||||
tokenApp, ok := (conn.App()).(*TokenBoardClient)
|
tokenApp, ok := (conn.App()).(*TokenBoardClient)
|
||||||
if ok {
|
if ok {
|
||||||
if spent, _ := tokenApp.Post(ct, sig); !spent {
|
if spent, numtokens := tokenApp.Post(ct, sig); !spent {
|
||||||
// TODO: while this works for the spam guard, it won't work for other forms of payment...
|
// we failed to post, probably because we ran out of tokens... so make a payment
|
||||||
// Make an -inline- payment, this will hold the goroutine
|
go tokenApp.MakePayment()
|
||||||
if err := tokenApp.MakePayment(); err == nil {
|
// backoff
|
||||||
// This really shouldn't fail since we now know we have the required tokens...
|
time.Sleep(time.Second)
|
||||||
if spent, numTokens := tokenApp.Post(ct, sig); !spent {
|
// try again
|
||||||
e.eventManager.Publish(event.NewEvent(event.SendMessageToGroupError, map[event.Field]string{event.GroupID: groupID, event.GroupServer: server, event.Error: fmt.Errorf("could not post %v", numTokens).Error(), event.Signature: base64.StdEncoding.EncodeToString(sig)}))
|
e.sendMessageToGroup(groupID, server, ct, sig, attempts+1)
|
||||||
}
|
} else {
|
||||||
} else {
|
if numtokens < 5 {
|
||||||
// Broadcast the token error
|
go tokenApp.MakePayment()
|
||||||
e.eventManager.Publish(event.NewEvent(event.SendMessageToGroupError, map[event.Field]string{event.GroupID: groupID, event.GroupServer: server, event.Error: err.Error(), event.Signature: base64.StdEncoding.EncodeToString(sig)}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// regardless we return....
|
// regardless we return....
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"git.openprivacy.ca/openprivacy/log"
|
"git.openprivacy.ca/openprivacy/log"
|
||||||
"github.com/gtank/ristretto255"
|
"github.com/gtank/ristretto255"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewTokenBoardClient generates a new Client for Token Board
|
// NewTokenBoardClient generates a new Client for Token Board
|
||||||
|
@ -190,24 +191,28 @@ func (ta *TokenBoardClient) MakePayment() error {
|
||||||
conn, _ = client.GetConnection(ta.tokenServiceOnion)
|
conn, _ = client.GetConnection(ta.tokenServiceOnion)
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Connect(ta.tokenServiceOnion, powTokenApp)
|
connected, err := client.Connect(ta.tokenServiceOnion, powTokenApp)
|
||||||
conn, err := client.WaitForCapabilityOrClose(ta.tokenServiceOnion, applications.HasTokensCapability)
|
if connected == true && err == nil {
|
||||||
if err == nil {
|
conn, err := client.WaitForCapabilityOrClose(ta.tokenServiceOnion, applications.HasTokensCapability)
|
||||||
powtapp, ok := conn.App().(*applications.TokenApplication)
|
if err == nil {
|
||||||
if ok {
|
powtapp, ok := conn.App().(*applications.TokenApplication)
|
||||||
// Update tokens...we need a lock here to prevent SpendToken from modifying the tokens
|
if ok {
|
||||||
// during this process..
|
// Update tokens...we need a lock here to prevent SpendToken from modifying the tokens
|
||||||
log.Debugf("Updating Tokens")
|
// during this process..
|
||||||
ta.tokenLock.Lock()
|
log.Debugf("Updating Tokens")
|
||||||
ta.tokens = append(ta.tokens, powtapp.Tokens...)
|
ta.tokenLock.Lock()
|
||||||
if len(ta.tokens) < 10 {
|
ta.tokens = append(ta.tokens, powtapp.Tokens...)
|
||||||
go ta.MakePayment()
|
ta.tokenLock.Unlock()
|
||||||
|
log.Debugf("Transcript: %v", powtapp.Transcript().OutputTranscriptToAudit())
|
||||||
|
conn.Close()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
ta.tokenLock.Unlock()
|
|
||||||
log.Debugf("Transcript: %v", powtapp.Transcript().OutputTranscriptToAudit())
|
|
||||||
conn.Close()
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.Debugf("failed to make a connection. trying again...")
|
||||||
|
// it doesn't actually take that long to make a payment, so waiting a small amount of time should suffice
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
return ta.MakePayment()
|
||||||
}
|
}
|
||||||
log.Debugf("Error making payment: to %v %v", ta.tokenServiceOnion, err)
|
log.Debugf("Error making payment: to %v %v", ta.tokenServiceOnion, err)
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in New Issue