| 1 | package bot |
| 2 | |
| 3 | // sessionClaim records the decision made while the controller map is locked. |
| 4 | type sessionClaim int |
| 5 | |
| 6 | const ( |
| 7 | sessionAbsent sessionClaim = iota |
| 8 | sessionReused |
| 9 | sessionChangeDeferred |
| 10 | sessionRetired |
| 11 | ) |
| 12 | |
| 13 | // claimSession always releases the gateway lock if a controller method |
| 14 | // panics. Controller calls are expected to be safe, but a failure must not |
| 15 | // wedge later messages and turn cleanup behind gw.mu. |
| 16 | func (gw *BotGateway) claimSession(key string, msg InboundMessage, profile sessionRuntimeProfile) (*sessionState, sessionClaim) { |
| 17 | gw.mu.Lock() |
| 18 | defer gw.mu.Unlock() |
| 19 | state, ok := gw.controllers[key] |
| 20 | switch { |
| 21 | case !ok: |
| 22 | return nil, sessionAbsent |
| 23 | case sessionStateMatchesRuntime(state, profile): |
| 24 | updateSessionStateRuntime(state, msg, profile) |
| 25 | return state, sessionReused |
| 26 | case botSessionHasActiveWork(state): |
| 27 | return state, sessionChangeDeferred |
| 28 | default: |
| 29 | delete(gw.controllers, key) |
| 30 | return state, sessionRetired |
| 31 | } |
| 32 | } |
| 33 |