diff options
author | Alex Auvolat <alex@adnab.me> | 2020-03-13 11:29:03 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2020-03-13 11:29:03 +0100 |
commit | ad8461491b35c739683971deff32a3203d0d7e5d (patch) | |
tree | b84f4e59b3a4771b0449714bce22ca78f1074fb3 | |
parent | 6292303a31e9098e8803c9544fc0785023d526fd (diff) | |
download | easybridge-ad8461491b35c739683971deff32a3203d0d7e5d.tar.gz easybridge-ad8461491b35c739683971deff32a3203d0d7e5d.zip |
Avoid occasionnal deadlocks (1 in 256)
-rw-r--r-- | account.go | 9 | ||||
-rw-r--r-- | server.go | 3 | ||||
-rw-r--r-- | util.go | 6 |
3 files changed, 9 insertions, 9 deletions
@@ -453,17 +453,16 @@ func (a *Account) eventInternal(event *Event) error { var cache_key string if event.Id != "" { + // Use mx_room_id as a lock slot key, because this section is + // concurrent with the part that sends events out in server.go, + // and at that point we don't know the event's ID yet + // since it will be attributed by the backend during the call to send dbLockSlot(mx_room_id) defer dbUnlockSlot(mx_room_id) // If the event has an ID, make sure it is processed only once cache_key = fmt.Sprintf("%s/event_seen/%s/%s", a.Protocol, mx_room_id, event.Id) - slot_key := dbKvSlotKey(cache_key) - - dbLockSlot(slot_key) - defer dbUnlockSlot(slot_key) - if dbKvGet(cache_key) == "yes" { // false: cache key was not modified, meaning we // already saw the event @@ -166,6 +166,7 @@ func handleTxnEvent(e *mxlib.Event) error { ev.Author = acct.Conn.User() ev.Room = room.RoomID + // use room id as lock slot key, see account.go in eventInternal dbLockSlot(e.RoomId) defer dbUnlockSlot(e.RoomId) @@ -173,7 +174,7 @@ func handleTxnEvent(e *mxlib.Event) error { if err == nil && created_ev_id != "" { cache_key := fmt.Sprintf("%s/event_seen/%s/%s", room.Protocol, e.RoomId, created_ev_id) - dbKvPut(cache_key, "yes") + dbKvPutLocked(cache_key, "yes") } return err } else { @@ -27,15 +27,15 @@ func ezbrSystemRoom(user_mx_id string) (string, error) { } widget_kv_key := "ezbr_widget_on:" + mx_room_id - if config.WebURL != "" && dbKvTestAndSet(widget_kv_key, "yes") { + if config.WebURL != "" && dbKvGet(widget_kv_key) != "yes" { widget := map[string]interface{}{ "type": "m.easybridge", "url": config.WebURL, "name": "Easybridge account configuration dashboard", } err = mx.PutStateAs(mx_room_id, "im.vector.modular.widgets", "ezbr_widget", widget, ezbrMxId()) - if err != nil { - dbKvPut(widget_kv_key, "") + if err == nil { + dbKvPut(widget_kv_key, "yes") } } |