From 9aa53aa3aa49447d475d35db37f4fb1dd6b6da58 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Fri, 26 Jun 2020 18:02:22 -0400 Subject: [PATCH 1/4] update lastSeen on reattach --- irc/getters.go | 1 + 1 file changed, 1 insertion(+) diff --git a/irc/getters.go b/irc/getters.go index f74e5f7c..1ba2c97c 100644 --- a/irc/getters.go +++ b/irc/getters.go @@ -106,6 +106,7 @@ func (client *Client) AddSession(session *Session) (success bool, numSessions in newSessions[len(newSessions)-1] = session if client.accountSettings.AutoreplayMissed || session.deviceID != "" { lastSeen = client.lastSeen[session.deviceID] + client.setLastSeen(time.Now().UTC(), session.deviceID) } client.sessions = newSessions if client.autoAway { From e22adf47ca1826b46a4ae8cc7424a96f9cd7c27f Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Fri, 26 Jun 2020 18:03:39 -0400 Subject: [PATCH 2/4] increase write interval for lastSeen --- irc/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irc/client.go b/irc/client.go index 2aae8dca..b9ba587d 100644 --- a/irc/client.go +++ b/irc/client.go @@ -34,7 +34,7 @@ const ( maxDeviceIDsPerClient = 64 // controls how often often we write an autoreplay-missed client's // deviceid->lastseentime mapping to the database - lastSeenWriteInterval = time.Minute * 10 + lastSeenWriteInterval = time.Hour ) // ResumeDetails is a place to stash data at various stages of From a38d375bda3848292360dacfe230adfa907f20e4 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Fri, 26 Jun 2020 18:23:33 -0400 Subject: [PATCH 3/4] delete always-on modes on unregistration --- irc/accounts.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/irc/accounts.go b/irc/accounts.go index f5ceb757..40a40022 100644 --- a/irc/accounts.go +++ b/irc/accounts.go @@ -1245,6 +1245,7 @@ func (am *AccountManager) Unregister(account string, erase bool) error { joinedChannelsKey := fmt.Sprintf(keyAccountJoinedChannels, casefoldedAccount) lastSeenKey := fmt.Sprintf(keyAccountLastSeen, casefoldedAccount) unregisteredKey := fmt.Sprintf(keyAccountUnregistered, casefoldedAccount) + modesKey := fmt.Sprintf(keyAccountModes, casefoldedAccount) var clients []*Client @@ -1299,6 +1300,7 @@ func (am *AccountManager) Unregister(account string, erase bool) error { tx.Delete(channelsKey) tx.Delete(joinedChannelsKey) tx.Delete(lastSeenKey) + tx.Delete(modesKey) _, err := tx.Delete(vhostQueueKey) am.decrementVHostQueueCount(casefoldedAccount, err) From 0f04acaa40f6f0362e36495135e3326f38d07b6c Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 29 Jun 2020 00:30:27 -0400 Subject: [PATCH 4/4] persist last seen on shutdown --- irc/client.go | 24 +++++++++++++++++++++--- irc/server.go | 3 +++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/irc/client.go b/irc/client.go index b9ba587d..bc36a41c 100644 --- a/irc/client.go +++ b/irc/client.go @@ -1724,7 +1724,7 @@ func (client *Client) wakeWriter() { func (client *Client) writeLoop() { for { - client.performWrite() + client.performWrite(0) client.writerSemaphore.Release() client.stateMutex.RLock() @@ -1737,9 +1737,9 @@ func (client *Client) writeLoop() { } } -func (client *Client) performWrite() { +func (client *Client) performWrite(additionalDirtyBits uint) { client.stateMutex.Lock() - dirtyBits := client.dirtyBits + dirtyBits := client.dirtyBits | additionalDirtyBits client.dirtyBits = 0 account := client.account client.stateMutex.Unlock() @@ -1775,3 +1775,21 @@ func (client *Client) performWrite() { client.server.accounts.saveModes(account, uModes) } } + +// Blocking store; see Channel.Store and Socket.BlockingWrite +func (client *Client) Store(dirtyBits uint) (err error) { + defer func() { + client.stateMutex.Lock() + isDirty := client.dirtyBits != 0 + client.stateMutex.Unlock() + + if isDirty { + client.wakeWriter() + } + }() + + client.writerSemaphore.Acquire() + defer client.writerSemaphore.Release() + client.performWrite(dirtyBits) + return nil +} diff --git a/irc/server.go b/irc/server.go index 98725553..8a5fbfb8 100644 --- a/irc/server.go +++ b/irc/server.go @@ -116,6 +116,9 @@ func (server *Server) Shutdown() { //TODO(dan): Make sure we disallow new nicks for _, client := range server.clients.AllClients() { client.Notice("Server is shutting down") + if client.AlwaysOn() { + client.Store(IncludeLastSeen) + } } if err := server.store.Close(); err != nil {