Closed is called when a connection has been closed
(conn protocol.Connection, err error)
| 1871 | |
| 1872 | // Closed is called when a connection has been closed |
| 1873 | func (m *model) Closed(conn protocol.Connection, err error) { |
| 1874 | connID := conn.ConnectionID() |
| 1875 | deviceID := conn.DeviceID() |
| 1876 | |
| 1877 | m.mut.Lock() |
| 1878 | conn, ok := m.connections[connID] |
| 1879 | if !ok { |
| 1880 | m.mut.Unlock() |
| 1881 | return |
| 1882 | } |
| 1883 | |
| 1884 | closed := m.closed[connID] |
| 1885 | delete(m.closed, connID) |
| 1886 | delete(m.connections, connID) |
| 1887 | |
| 1888 | removedIsPrimary := m.promotedConnID[deviceID] == connID |
| 1889 | remainingConns := without(m.deviceConnIDs[deviceID], connID) |
| 1890 | var wait <-chan error |
| 1891 | if removedIsPrimary { |
| 1892 | m.progressEmitter.temporaryIndexUnsubscribe(conn) |
| 1893 | if idxh, ok := m.indexHandlers.Get(deviceID); ok && idxh.conn.ConnectionID() == connID { |
| 1894 | wait = m.indexHandlers.RemoveAndWaitChan(deviceID, 0) |
| 1895 | } |
| 1896 | m.scheduleConnectionPromotion() |
| 1897 | } |
| 1898 | if len(remainingConns) == 0 { |
| 1899 | // All device connections closed |
| 1900 | delete(m.deviceConnIDs, deviceID) |
| 1901 | delete(m.promotedConnID, deviceID) |
| 1902 | delete(m.connRequestLimiters, deviceID) |
| 1903 | delete(m.helloMessages, deviceID) |
| 1904 | delete(m.remoteFolderStates, deviceID) |
| 1905 | delete(m.deviceDownloads, deviceID) |
| 1906 | } else { |
| 1907 | // Some connections remain |
| 1908 | m.deviceConnIDs[deviceID] = remainingConns |
| 1909 | } |
| 1910 | |
| 1911 | m.mut.Unlock() |
| 1912 | if wait != nil { |
| 1913 | <-wait |
| 1914 | } |
| 1915 | |
| 1916 | m.mut.RLock() |
| 1917 | m.deviceDidCloseRLocked(deviceID, time.Since(conn.EstablishedAt())) |
| 1918 | m.mut.RUnlock() |
| 1919 | |
| 1920 | k := map[bool]string{false: "secondary", true: "primary"}[removedIsPrimary] |
| 1921 | slog.Info("Lost device connection", slog.String("kind", k), deviceID.LogAttr(), slog.Any("connection", conn), slogutil.Error(err), slog.Int("remaining", len(remainingConns))) |
| 1922 | |
| 1923 | if len(remainingConns) == 0 { |
| 1924 | slog.Info("Connection closed", deviceID.LogAttr(), slog.Any("connection", conn), slogutil.Error(err)) |
| 1925 | m.evLogger.Log(events.DeviceDisconnected, map[string]string{ |
| 1926 | "id": deviceID.String(), |
| 1927 | "error": err.Error(), |
| 1928 | }) |
| 1929 | } |
| 1930 | close(closed) |
nothing calls this directly
no test coverage detected