Skip to content

Commit b519590

Browse files
committed
docs: ADR for publishing a RabbitMQ settings update message
1 parent 7c0b9ca commit b519590

1 file changed

Lines changed: 116 additions & 0 deletions

File tree

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# ADR: Replace Common Settings HTTP API with RabbitMQ Publishing
2+
3+
## Status
4+
5+
**Proposed**
6+
7+
## Context
8+
9+
The cozy-stack currently synchronizes user settings with an external "common settings" application via HTTP API calls.
10+
This integration is implemented in `model/settings/common/common.go` and performs:
11+
12+
1. **HTTP POST** to `/api/admin/user/settings` when creating settings
13+
2. **HTTP GET** to `/api/admin/user/settings/{nickname}` to check remote version
14+
3. **HTTP PUT** to `/api/admin/user/settings/{nickname}` to update settings
15+
16+
This approach has several issues:
17+
18+
- **Synchronous blocking**: HTTP calls block the settings update operation
19+
- **Version conflict complexity**: The code checks remote versions before updates, creating complex conflict resolution logic
20+
- **Tight coupling**: Direct HTTP dependency on the common settings app
21+
- **Failure propagation**: HTTP failures can affect the main settings update flow
22+
- **No longer needed**: The common settings app is no longer actively updating settings, making version conflict checking obsolete
23+
24+
The codebase already has a mature RabbitMQ infrastructure for message consumption (password updates, user creation, phone updates, subscription changes, app lifecycle).
25+
This infrastructure can be extended for publishing.
26+
27+
## Proposal
28+
29+
Replace the HTTP API calls with RabbitMQ message publishing using a fire-and-forget pattern:
30+
31+
### Architecture
32+
33+
```mermaid
34+
flowchart LR
35+
subgraph CozyStack["cozy-stack"]
36+
Publisher["Publisher"]
37+
end
38+
39+
subgraph Storage["Storage"]
40+
CouchDB["CouchDB<br/>(settings)"]
41+
end
42+
43+
subgraph MessageBroker["Message Broker"]
44+
RabbitMQ["RabbitMQ<br/>(exchange: settings)"]
45+
end
46+
47+
subgraph Consumer["TWP app"]
48+
CommonSettings["Common Settings<br/>(consume)"]
49+
end
50+
51+
Publisher -->|"1. Update settings"| CouchDB
52+
Publisher -->|"2. Publish message"| RabbitMQ
53+
RabbitMQ -->|"user.settings.updated"| CommonSettings
54+
```
55+
56+
### Key Changes
57+
58+
1. **New Publisher Infrastructure** (`pkg/rabbitmq/publisher.go`)
59+
- Reuses existing `RabbitMQConnection` for connection management
60+
- Provides thread-safe publishing with automatic channel recovery
61+
- JSON serialization with persistent delivery mode
62+
63+
2. **Service Layer Extension** (`pkg/rabbitmq/service.go`)
64+
- Add publishing capabilities alongside existing consumers
65+
- Context-aware publisher selection (same as consumers)
66+
67+
3. **Simplified Common Settings Module** (`model/settings/common/common.go`)
68+
- Replace HTTP calls with RabbitMQ publishing
69+
- Remove version conflict checking (local DB is source of truth)
70+
- Fire-and-forget: log errors but don't fail the operation
71+
72+
### Configuration
73+
74+
```yaml
75+
rabbitmq:
76+
enabled: true
77+
nodes:
78+
default:
79+
url: amqp://guest:guest@localhost:5672/
80+
publishing:
81+
common_settings:
82+
exchange: "settings"
83+
routing_key: "user.settings.updated"
84+
```
85+
86+
### Message Format
87+
88+
Preserve existing message structure for backward compatibility:
89+
90+
```json
91+
{
92+
"source": "cozy-stack",
93+
"nickname": "user-slug",
94+
"request_id": "domain_1234567890",
95+
"timestamp": 1234567890,
96+
"version": 2,
97+
"payload": {
98+
"language": "en",
99+
"timezone": "Europe/Paris",
100+
"first_name": "John",
101+
"last_name": "Doe",
102+
"display_name": "John Doe",
103+
"email": "john@example.com",
104+
"phone": "+33612345678",
105+
"matrix_id": "@john:example.com",
106+
"avatar": "https://cozy.example.com/public/avatar?v=2"
107+
}
108+
}
109+
```
110+
111+
## Alternatives
112+
113+
## Decision
114+
115+
## Consequences
116+

0 commit comments

Comments
 (0)