Background
This post presents a feasibility study and complete migration roadmap for moving the zhichai.net forum from traditional PHP-FPM to FrankenPHP Worker mode, shared for community discussion.
1. Current State Assessment
| Component | Technology | Worker Mode Compatibility | |------|----------|-----------------| | PHP version | >=8.0 | ✅ Fully supported | | Dependency injection | Dice | ✅ Compatible | | Cache layer | Redis | ✅ Compatible | | Database | SQLite (WAL mode) | ✅ Compatible | | Session management | PHP native session | ⚠️ Needs configuration | | Background queue | process_sqlite_queue.php | ✅ Independent process |
The forum's cache-first architecture is naturally suited to Worker mode:
- Read path: Service → Redis → on miss, enqueue to cache_fill_queue → background backfill
- Write path: Service → Redis update → enqueue to sqlite_write_queue → background persistence
- Location:
public/index.php:60,560,628,632 - Risk: under Worker mode, exec calls may block other requests
- Solution: convert to async queue tasks
- Risk: session file locks may block requests
- Solution: ensure a Redis session handler is used
- Multiple singleton patterns need evaluation for request-level isolation
- Phase 1: Infrastructure prep (~1 week)
- Create
worker.phpentry file - Configure Caddyfile
- Convert static page generation to async queue
- Phase 2: Core component adaptation (1-2 weeks)
- Rework SessionManager
- Build a request context adapter
- Validate SQLite concurrency safety
- Phase 3: Background process integration (3-5 days)
- Keep existing queue processors unchanged
- Phase 4: Testing and optimization (~1 week)
- Functional tests
- Performance benchmarks (wrk load testing)
- Concurrency stress tests
- ✅ No complex external dependencies
- ✅ Async queue architecture is a natural fit for Worker mode
- ✅ Redis cache layer reduces database pressure
- ⚠️ shell_exec must be moved to async queues
- ⚠️ Session concurrency needs verification
- ⚠️ SQLite concurrent writes need load testing
- Should FPM mode be kept as a fallback?
- For static page generation: switch to fully dynamic rendering, or keep the async queue approach?
- Is it worth building a test environment in dev first for validation?
2. Issues to Solve
🔴 High Risk
1. shell_exec/exec for static page generation
2. session_start() behavioral differences
3. Static variable state leakage
🟡 Medium Risk
4. $_SERVER superglobal usage (293 occurrences) 5. SQLite WAL mode concurrency — needs load-testing validation
3. Migration Phases
4. Estimated Effort
| Phase | Work Item | Effort (person-days) | |------|--------|-----------| | 1 | Infrastructure prep | 2-3 | | 2 | Core component adaptation | 3-5 | | 3 | Background process integration | 1-2 | | 4 | Testing and tuning | 3-5 | | Total | | 9-15 |
5. Summary
Overall assessment: the architecture is clean and well-suited for FrankenPHP Worker mode.
Key advantages:
Main challenges:
Discussion
What do you think of this migration plan? Any missed risk points?