-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture Overview Service Layer Design
**Referenced Files in This Document** - [DynamicPterodactyl.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/DynamicPterodactyl.php) - [ResourceCalculationService.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Services/ResourceCalculationService.php) - [ReservationService.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Services/ReservationService.php) - [NodeSelectionService.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Services/NodeSelectionService.php) - [AlertService.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Services/AlertService.php) - [AvailabilityController.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Http/Controllers/Api/AvailabilityController.php) - [ReservationController.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Http/Controllers/Api/ReservationController.php) - [AdminCapacityController.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Http/Controllers/Api/Admin/AdminCapacityController.php) - [ResourceReservation.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Models/ResourceReservation.php)Preserved Qoder snapshot. This deep-dive page is retained so the earlier Wiki work and its source trail are not lost. For the reconciled implementation, Architecture Overview is canonical; references below to retired controllers, listeners, services, or API shapes are historical.
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
This document explains the service-oriented design that encapsulates business logic for dynamic Pterodactyl resource reservations and availability. It focuses on how ResourceCalculationService, ReservationService, and NodeSelectionService provide clear separation between API controllers and data access layers, how they compose together to implement complex workflows, and how errors, transactions, and external API failures are handled gracefully.
The extension integrates with Paymenter’s event system to create, confirm, cancel, and expire reservations while keeping Pterodactyl API calls isolated in a dedicated service layer. Customer-facing endpoints return only aggregate capacity information; node-level details are reserved for admin endpoints.
At a high level:
- Controllers expose HTTP APIs and delegate business logic to services.
- Services encapsulate domain rules, coordinate external systems (Pterodactyl), and manage persistence through database queries or models.
- The extension bootstraps routes, policies, listeners, and scheduled tasks from DynamicPterodactyl.php.
graph TB
Client["HTTP Client"] --> AvailCtrl["AvailabilityController"]
Client --> ResCtrl["ReservationController"]
Client --> AdminCapCtrl["AdminCapacityController"]
AvailCtrl --> NodeSelSvc["NodeSelectionService"]
AvailCtrl --> ResCalcSvc["ResourceCalculationService"]
ResCtrl --> ResSvc["ReservationService"]
AdminCapCtrl --> ResCalcSvc
NodeSelSvc --> ResCalcSvc
ResSvc --> NodeSelSvc
ResCalcSvc --> PteroAPI["Pterodactyl API"]
ResSvc --> DB[("ptero_resource_reservations")]
ResCalcSvc --> DB
Diagram sources
- AvailabilityController.php:22-69
- ReservationController.php:24-136
- AdminCapacityController.php:17-61
- NodeSelectionService.php:22-86
- ResourceCalculationService.php:26-141
- ReservationService.php:43-141
Section sources
- ResourceCalculationService: Encapsulates all Pterodactyl API interactions, builds real-time availability snapshots, and aggregates per-location and per-node metrics. It never caches responses; it batches API calls where possible and degrades gracefully when the upstream is unavailable.
- NodeSelectionService: Implements best-fit node selection using weighted headroom scoring across memory, disk, and CPU. It depends on ResourceCalculationService for live availability.
- ReservationService: Manages reservation lifecycle (create, confirm, cancel, extend, cleanup). It uses database transactions with pessimistic locking and idempotency support. It delegates node selection to NodeSelectionService.
- AlertService: Periodically checks capacity thresholds and sends notifications via email/webhooks. It depends on ResourceCalculationService for current utilization data.
- Controllers: Thin HTTP boundaries that validate input, enforce authorization, and call services. They translate exceptions into user-friendly JSON responses.
Section sources
- ResourceCalculationService.php:10-222
- NodeSelectionService.php:5-86
- ReservationService.php:16-453
- AlertService.php:19-392
- AvailabilityController.php:9-71
- ReservationController.php:13-137
- AdminCapacityController.php:8-62
The service layer enforces strict boundaries:
- Controllers do not talk directly to Pterodactyl or perform complex calculations.
- ResourceCalculationService isolates all Pterodactyl API calls, including pagination, retries, error mapping, and degraded snapshot fallbacks.
- NodeSelectionService contains allocation strategy without leaking implementation details to controllers.
- ReservationService owns reservation state transitions, concurrency control, and idempotency guarantees.
sequenceDiagram
participant C as "Client"
participant A as "AvailabilityController"
participant N as "NodeSelectionService"
participant R as "ResourceCalculationService"
participant P as "Pterodactyl API"
C->>A : GET /availability/{locationId}
A->>R : getLocationAvailability(locationId)
R->>P : GET /locations/{id}?include=nodes,servers
P-->>R : JSON payload
R-->>A : location availability
A->>N : getMaxAvailable(locationId, locationData)
N-->>A : max_available from same snapshot
A-->>C : {max_memory,max_cpu,max_disk,...}
Diagram sources
- AvailabilityController.php:22-52
- NodeSelectionService.php:81-86
- ResourceCalculationService.php:26-67
- ResourceCalculationService.php:359-384
Responsibilities:
- Fetch locations and nodes from Pterodactyl, including server relationships.
- Compute effective node capacity using overallocation settings and thread-based CPU.
- Aggregate per-location totals and maximum available resources.
- Provide cluster snapshot building with fallback behavior when Pterodactyl is partially unavailable.
- Validate availability at payment time against pending reservations.
Key behaviors:
- Real-time API calls with short timeouts and limited retries for connection errors.
- Paginated retrieval for large clusters.
- Degraded snapshot returns minimal structure when upstream fails with server errors or connectivity issues.
- Pending reservations are subtracted from available resources to avoid double-booking.
Error handling:
- Connection exceptions are reported and converted to sanitized runtime exceptions.
- Rate limiting (429) and failed responses are logged and surfaced as runtime exceptions.
- Invalid JSON payloads are rejected with descriptive errors.
flowchart TD
Start(["getLocationAvailability"]) --> FetchNodes["Fetch location with nodes and servers"]
FetchNodes --> ForEachNode["For each node"]
ForEachNode --> CalcNode["Calculate node availability<br/>+ pending reservations"]
CalcNode --> Aggregate["Aggregate totals and max available"]
Aggregate --> Return(["Return location data"])
Diagram sources
- ResourceCalculationService.php:26-67
- ResourceCalculationService.php:146-152
- ResourceCalculationService.php:227-257
Section sources
- ResourceCalculationService.php:26-222
- ResourceCalculationService.php:291-384
- ResourceCalculationService.php:410-498
Responsibilities:
- Select the best node for given resource requirements using a weighted headroom algorithm.
- Skip nodes in maintenance mode.
- Expose maximum allocatable resources per location.
Algorithm highlights:
- Filters candidates by hard constraints (memory, CPU, disk).
- Scores remaining headroom with weights: memory 50%, disk 35%, CPU 15%.
- Returns the highest-scoring node or null if none fit.
flowchart TD
S(["selectBestNode"]) --> LoadAvail["Load location availability"]
LoadAvail --> Filter["Filter out maintenance & insufficient nodes"]
Filter --> Score["Score by weighted headroom"]
Score --> Sort["Sort descending by score"]
Sort --> Choose{"Any candidates?"}
Choose -- "No" --> None["Return null"]
Choose -- "Yes" --> Best["Return top node"]
Diagram sources
Section sources
Responsibilities:
- Create reservations with idempotency and TTL.
- Confirm, cancel, and extend reservations with authorization checks.
- Clean up expired reservations via scheduled task.
- Provide statistics and query builders for admin usage.
Concurrency and transactions:
- Uses database transactions with lockForUpdate on pending reservations within the target location to prevent races.
- Retries up to five times on deadlock conditions.
- Idempotency key deduplicates concurrent requests and handles race conditions after unique constraint violations.
Authorization:
- Optional actor parameter triggers policy checks for confirm/cancel/extend operations.
Auditability:
- Audits key actions (create, confirm, cancel, extend, batch expiry) via a shared concern.
sequenceDiagram
participant C as "Client"
participant Ctrl as "ReservationController"
participant Svc as "ReservationService"
participant N as "NodeSelectionService"
participant R as "ResourceCalculationService"
participant DB as "Database"
C->>Ctrl : POST create reservation
Ctrl->>Svc : create(productId, locationId, resources, ...)
Svc->>DB : BEGIN transaction + lockForUpdate(pending)
Svc->>N : selectBestNode(locationId, resources)
N->>R : getLocationAvailability(locationId)
R-->>N : availability
N-->>Svc : best node or null
alt No suitable node
Svc-->>Ctrl : RuntimeException
else Node found
Svc->>DB : INSERT reservation (pending, TTL)
Svc-->>Ctrl : reservation payload
end
Diagram sources
- ReservationController.php:24-60
- ReservationService.php:43-141
- NodeSelectionService.php:22-76
- ResourceCalculationService.php:26-67
Section sources
Responsibilities:
- Periodically check capacity thresholds per configured scope (all locations or specific location).
- Send notifications via email and webhooks with delivery logging and failure events.
- Notify administrators about reservation shortfalls or state drift after payment.
Error handling:
- Gracefully logs and reports notification failures without breaking alert cycles.
- Emits an event when all channels fail to deliver.
Section sources
- AvailabilityController: Returns aggregate capacity and node counts for customer-facing endpoints. It does not expose raw node identifiers or per-node capacities.
- ReservationController: Validates input, authorizes actions, and delegates to ReservationService. Converts service exceptions into consistent JSON responses.
- AdminCapacityController: Builds a full cluster snapshot for administrative use, including node-level details.
Section sources
Service composition and coupling:
- NodeSelectionService depends on ResourceCalculationService for live availability.
- ReservationService depends on NodeSelectionService for node choice and on the database for persistence.
- AlertService depends on ResourceCalculationService for utilization metrics.
- Controllers depend on services only; no direct Pterodactyl calls or complex logic.
classDiagram
class ResourceCalculationService {
+getLocationAvailability()
+buildClusterSnapshot()
+verifyAvailability()
+getLocations()
+testConnection()
}
class NodeSelectionService {
+selectBestNode()
+getMaxAvailable()
}
class ReservationService {
+create()
+confirm()
+cancel()
+extend()
+cleanupExpired()
+getStatistics()
}
class AlertService {
+checkCapacityAlerts()
+sendTestNotification()
+notifyShortfall()
}
class AvailabilityController
class ReservationController
class AdminCapacityController
NodeSelectionService --> ResourceCalculationService : "uses"
ReservationService --> NodeSelectionService : "uses"
AlertService --> ResourceCalculationService : "uses"
AvailabilityController --> NodeSelectionService : "uses"
AvailabilityController --> ResourceCalculationService : "uses"
ReservationController --> ReservationService : "uses"
AdminCapacityController --> ResourceCalculationService : "uses"
Diagram sources
- NodeSelectionService.php:5-86
- ReservationService.php:16-453
- AlertService.php:19-392
- AvailabilityController.php:9-71
- ReservationController.php:13-137
- AdminCapacityController.php:8-62
Section sources
- Real-time availability: All availability data is fetched live from Pterodactyl; there is no caching. This ensures accuracy but increases dependency on upstream latency.
- Batching and pagination: Cluster snapshot and node fetching use paginated endpoints to handle large deployments efficiently.
- Short timeouts and retries: API calls use small timeouts and retry only on transient connection errors to avoid long request lifetimes.
- Aggregation cost: Per-location aggregation computes totals and maximums across nodes; consider rate limits and upstream performance under load.
- Scheduled tasks: Cleanup and alert checks run periodically to keep state consistent and reduce controller burden.
[No sources needed since this section provides general guidance]
Common issues and where to look:
- Pterodactyl connectivity failures:
- ResourceCalculationService converts connection exceptions into sanitized runtime exceptions and reports them. Check logs for connection diagnostics and ensure configuration values are correct.
- Use testConnection to verify panel URL and API key.
- Rate limiting:
- 429 responses are treated as rate limit errors; back off and retry later.
- Invalid responses:
- Non-JSON or malformed payloads cause explicit errors; inspect upstream changes or version compatibility.
- Deadlocks during reservation creation:
- ReservationService retries up to five times on deadlocks. If persistent, review contention on pending reservations and consider tuning workload patterns.
- Authorization failures:
- ReservationService enforces policies when an actor is provided. Ensure users have appropriate permissions to confirm, cancel, or extend reservations.
- Notification delivery failures:
- AlertService logs channel-specific failures and emits events when all channels fail. Inspect delivery logs and recipient configurations.
Section sources
- ResourceCalculationService.php:158-195
- ResourceCalculationService.php:452-498
- ReservationService.php:43-141
- ReservationService.php:166-281
- AlertService.php:128-248
The service layer cleanly separates concerns:
- ResourceCalculationService isolates Pterodactyl integration and provides accurate, real-time availability.
- NodeSelectionService encapsulates allocation strategy and remains independent of persistence and HTTP concerns.
- ReservationService manages reservation state, concurrency, idempotency, and auditability while delegating node selection.
- Controllers remain thin, focusing on validation, authorization, and response formatting.
This design supports robust workflows across checkout, confirmation, cancellation, and monitoring, while maintaining clear boundaries and graceful degradation when external systems are unavailable.
[No sources needed since this section summarizes without analyzing specific files]
DynamicPterodactyl · Dynamic Resource Sliders for Paymenter × Pterodactyl · Reviewed code checkpoint · Publication commits intentionally pin their latest code-bearing predecessor because a Git commit cannot self-reference its unknown object ID.
DynamicPterodactyl
Guides
Architecture
- Architecture Overview
Core Services
API Reference
Database
System