Skip to content

Commit 7196705

Browse files
docs: Add thread-safe mode specification
Simple spec for blocking global state access in multi-tenant environments. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 3e75a16 commit 7196705

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

docs/design/thread-safe-mode.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Thread-Safe Mode Specification
2+
3+
## Problem
4+
5+
DataJoint uses global state (`dj.config`, `dj.conn()`) that is not thread-safe. Multi-tenant applications (web servers, async workers) need isolated connections per request/task.
6+
7+
## Solution
8+
9+
Add `thread_safe` mode that blocks global state access and requires explicit connection configuration.
10+
11+
## API
12+
13+
### Enable Thread-Safe Mode
14+
15+
Set via environment variable or config file (read-only after initialization):
16+
17+
```bash
18+
export DJ_THREAD_SAFE=true
19+
```
20+
21+
```json
22+
// datajoint.json
23+
{"thread_safe": true}
24+
```
25+
26+
### Create Connections
27+
28+
```python
29+
conn = dj.Connection.from_config(
30+
host="localhost",
31+
user="user",
32+
password="password"
33+
)
34+
schema = dj.Schema("my_schema", connection=conn)
35+
```
36+
37+
## Behavior
38+
39+
| Operation | `thread_safe=False` | `thread_safe=True` |
40+
|-----------|--------------------|--------------------|
41+
| `dj.config.X` | Works | Raises `ThreadSafetyError` |
42+
| `dj.conn()` | Works | Raises `ThreadSafetyError` |
43+
| `dj.Schema("name")` | Works | Raises `ThreadSafetyError` |
44+
| `Connection.from_config()` | Works | Works |
45+
| `Schema(..., connection=conn)` | Works | Works |
46+
47+
## Implementation
48+
49+
1. Add `thread_safe: bool = False` field to `Config` with `DJ_THREAD_SAFE` env alias
50+
2. Make `thread_safe` read-only after `Config` initialization
51+
3. Add guards to `Config.__getattr__`, `Config.__setattr__`, `Config.__getitem__`, `Config.__setitem__`
52+
4. Add guard to `dj.conn()`
53+
5. Add guard to `Schema.__init__` when `connection=None`
54+
6. Add `Connection.from_config()` class method
55+
7. Add `ThreadSafetyError` exception
56+
57+
## Exceptions
58+
59+
```python
60+
class ThreadSafetyError(DataJointError):
61+
"""Raised when accessing global state in thread-safe mode."""
62+
```
63+
64+
Error messages:
65+
- Config access: `"Global config is inaccessible in thread-safe mode. Use Connection.from_config() with explicit configuration."`
66+
- `dj.conn()`: `"dj.conn() is disabled in thread-safe mode. Use Connection.from_config() with explicit configuration."`
67+
- Schema without connection: `"Schema requires explicit connection in thread-safe mode. Use Schema(..., connection=conn)."`

0 commit comments

Comments
 (0)