Packages
snakepit
0.1.2
0.13.0
0.12.0
0.11.1
0.11.0
0.10.1
0.10.0
0.9.1
0.9.0
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
High-performance pooler and session manager for external language integrations. Supports Python, Node.js, Ruby, and more with gRPC streaming, session management, and production-ready process cleanup.
Current section
53 Versions
Jump to
Current section
53 Versions
Compare versions
4
files changed
+82
additions
-42
deletions
| @@ -2,12 +2,14 @@ | |
| 2 2 | |
| 3 3 | ```mermaid |
| 4 4 | graph LR |
| 5 | - subgraph "Elixir/OTP Layer" |
| 5 | + ElixirOTPLayer["Elixir OTP Layer"] |
| 6 | + subgraph ElixirOTPLayer |
| 6 7 | Client["Client API"] |
| 7 8 | Pool["Pool Manager<br/>⚡ Non-blocking async"] |
| 8 9 | TaskSup["Task Supervisor<br/>⚡ Isolated execution"] |
| 9 10 | |
| 10 | - subgraph "Worker Management" |
| 11 | + WorkerManagement["Worker Management"] |
| 12 | + subgraph WorkerManagement |
| 11 13 | WorkerSup["Worker Supervisor<br/>⚡ Dynamic workers"] |
| 12 14 | Starter1["Worker Starter 1<br/>🔄 Auto-restart"] |
| 13 15 | Starter2["Worker Starter 2<br/>🔄 Auto-restart"] |
| @@ -17,19 +19,22 @@ graph LR | |
| 17 19 | WorkerN["Worker N<br/>GenServer"] |
| 18 20 | end |
| 19 21 | |
| 20 | - subgraph "High-Performance Registries" |
| 22 | + HighPerformanceRegistries["High Performance Registries"] |
| 23 | + subgraph HighPerformanceRegistries |
| 21 24 | Registry["Worker Registry<br/>⚡ O(1) lookups"] |
| 22 25 | ProcReg["Process Registry<br/>⚡ PID tracking"] |
| 23 26 | StarterReg["Starter Registry<br/>⚡ Supervisor tracking"] |
| 24 27 | end |
| 25 28 | |
| 26 | - subgraph "Session Store (ETS)" |
| 29 | + SessionStoreETS["Session Store ETS"] |
| 30 | + subgraph SessionStoreETS |
| 27 31 | SessionStore["Session Store<br/>⚡ Concurrent R/W<br/>📊 Decentralized counters"] |
| 28 32 | GlobalPrograms["Global Programs<br/>⚡ Public table access"] |
| 29 33 | end |
| 30 34 | end |
| 31 35 | |
| 32 | - subgraph "External Processes" |
| 36 | + ExternalProcesses["External Processes"] |
| 37 | + subgraph ExternalProcesses |
| 33 38 | Python1["Python Process 1<br/>🐍 Port communication"] |
| 34 39 | Python2["Python Process 2<br/>🐍 Port communication"] |
| 35 40 | PythonN["Python Process N<br/>🐍 Port communication"] |
| @@ -63,10 +68,15 @@ graph LR | |
| 63 68 | Worker2 -->|Track PID| ProcReg |
| 64 69 | WorkerN -->|Track PID| ProcReg |
| 65 70 | |
| 66 | - style Pool fill:#f9f,stroke:#333,stroke-width:4px,color:#000 |
| 67 | - style SessionStore fill:#bbf,stroke:#333,stroke-width:4px,color:#000 |
| 68 | - style Registry fill:#bfb,stroke:#333,stroke-width:4px,color:#000 |
| 69 | - style TaskSup fill:#fbf,stroke:#333,stroke-width:4px,color:#000 |
| 71 | + style ElixirOTPLayer fill:#e6e6fa,stroke:#9370db,stroke-width:3px,color:#2e1065 |
| 72 | + style WorkerManagement fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 73 | + style HighPerformanceRegistries fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 74 | + style SessionStoreETS fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 75 | + style ExternalProcesses fill:#f0f9ff,stroke:#0ea5e9,stroke-width:2px,color:#0c4a6e |
| 76 | + style Pool fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 77 | + style SessionStore fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 78 | + style Registry fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 79 | + style TaskSup fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 70 80 | ``` |
| 71 81 | |
| 72 82 | ## 2. Request Flow - Performance Critical Path |
| @@ -113,8 +123,10 @@ sequenceDiagram | |
| 113 123 | |
| 114 124 | ```mermaid |
| 115 125 | graph LR |
| 116 | - subgraph "Session Store ETS Tables" |
| 117 | - subgraph "Sessions Table" |
| 126 | + SessionStoreETSTables["Session Store ETS Tables"] |
| 127 | + subgraph SessionStoreETSTables |
| 128 | + SessionsTable["Sessions Table"] |
| 129 | + subgraph SessionsTable |
| 118 130 | ST[":snakepit_sessions<br/>⚡ read_concurrency: true<br/>⚡ write_concurrency: true<br/>⚡ decentralized_counters: true"] |
| 119 131 | |
| 120 132 | S1["Key: session_1<br/>Value: {last_accessed, ttl, session_data}"] |
| @@ -122,7 +134,8 @@ graph LR | |
| 122 134 | SN["Key: session_N<br/>Value: {last_accessed, ttl, session_data}"] |
| 123 135 | end |
| 124 136 | |
| 125 | - subgraph "Global Programs Table" |
| 137 | + GlobalProgramsTable["Global Programs Table"] |
| 138 | + subgraph GlobalProgramsTable |
| 126 139 | GP[":snakepit_sessions_global_programs<br/>⚡ Same optimizations"] |
| 127 140 | |
| 128 141 | P1["Key: program_1<br/>Value: {data, timestamp}"] |
| @@ -131,7 +144,8 @@ graph LR | |
| 131 144 | end |
| 132 145 | end |
| 133 146 | |
| 134 | - subgraph "Optimized Operations" |
| 147 | + OptimizedOperations["Optimized Operations"] |
| 148 | + subgraph OptimizedOperations |
| 135 149 | Read["⚡ Concurrent reads<br/>No locking"] |
| 136 150 | Write["⚡ Concurrent writes<br/>Decentralized counters"] |
| 137 151 | Cleanup["⚡ select_delete<br/>Atomic batch cleanup"] |
| @@ -152,11 +166,15 @@ graph LR | |
| 152 166 | Cleanup --> ST |
| 153 167 | Cleanup --> GP |
| 154 168 | |
| 155 | - style ST fill:#bbf,stroke:#333,stroke-width:4px,color:#000 |
| 156 | - style GP fill:#bbf,stroke:#333,stroke-width:4px,color:#000 |
| 157 | - style Read fill:#bfb,stroke:#333,stroke-width:2px,color:#000 |
| 158 | - style Write fill:#bfb,stroke:#333,stroke-width:2px,color:#000 |
| 159 | - style Cleanup fill:#fbb,stroke:#333,stroke-width:2px,color:#000 |
| 169 | + style SessionStoreETSTables fill:#e6e6fa,stroke:#9370db,stroke-width:3px,color:#2e1065 |
| 170 | + style SessionsTable fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 171 | + style GlobalProgramsTable fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 172 | + style OptimizedOperations fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 173 | + style ST fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 174 | + style GP fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 175 | + style Read fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 176 | + style Write fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 177 | + style Cleanup fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 160 178 | ``` |
| 161 179 | |
| 162 180 | ## 4. Worker Lifecycle - Performance & Reliability |
| @@ -204,7 +222,8 @@ stateDiagram-v2 | |
| 204 222 | |
| 205 223 | ```mermaid |
| 206 224 | graph TD |
| 207 | - subgraph "Sequential Startup (Traditional)" |
| 225 | + SequentialStartupTraditional["Sequential Startup Traditional"] |
| 226 | + subgraph SequentialStartupTraditional |
| 208 227 | T0["Start"] --> W1S["Worker 1<br/>2s"] |
| 209 228 | W1S --> W2S["Worker 2<br/>2s"] |
| 210 229 | W2S --> W3S["Worker 3<br/>2s"] |
| @@ -212,7 +231,8 @@ graph TD | |
| 212 231 | W4S --> DoneS["Ready<br/>Total: 8s"] |
| 213 232 | end |
| 214 233 | |
| 215 | - subgraph "Concurrent Startup (Snakepit)" |
| 234 | + ConcurrentStartupSnakepit["Concurrent Startup Snakepit"] |
| 235 | + subgraph ConcurrentStartupSnakepit |
| 216 236 | T0C["Start"] --> Init["Task.async_stream"] |
| 217 237 | Init --> W1C["Worker 1<br/>2s"] |
| 218 238 | Init --> W2C["Worker 2<br/>2s"] |
| @@ -227,17 +247,21 @@ graph TD | |
| 227 247 | Collect --> DoneC["Ready<br/>Total: ~2s"] |
| 228 248 | end |
| 229 249 | |
| 230 | - style Init fill:#f9f,stroke:#333,stroke-width:4px,color:#000 |
| 231 | - style DoneC fill:#bfb,stroke:#333,stroke-width:4px,color:#000 |
| 232 | - style DoneS fill:#fbb,stroke:#333,stroke-width:2px,color:#000 |
| 250 | + style SequentialStartupTraditional fill:#fef3c7,stroke:#f59e0b,stroke-width:2px,color:#92400e |
| 251 | + style ConcurrentStartupSnakepit fill:#e6e6fa,stroke:#9370db,stroke-width:3px,color:#2e1065 |
| 252 | + style Init fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 253 | + style DoneC fill:#dcfce7,stroke:#22c55e,stroke-width:2px,color:#14532d |
| 254 | + style DoneS fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d |
| 233 255 | ``` |
| 234 256 | |
| 235 257 | ## 6. Request Queueing & Load Distribution |
| 236 258 | |
| 237 259 | ```mermaid |
| 238 260 | graph LR |
| 239 | - subgraph "High-Performance Request Handling" |
| 240 | - subgraph "Request Queue" |
| 261 | + HighPerformanceRequestHandling["High Performance Request Handling"] |
| 262 | + subgraph HighPerformanceRequestHandling |
| 263 | + RequestQueue["Request Queue"] |
| 264 | + subgraph RequestQueue |
| 241 265 | Q[":queue (Erlang)<br/>⚡ FIFO<br/>⚡ O(1) operations"] |
| 242 266 | R1["Request 1"] |
| 243 267 | R2["Request 2"] |
| @@ -245,7 +269,8 @@ graph LR | |
| 245 269 | RN["Request N"] |
| 246 270 | end |
| 247 271 | |
| 248 | - subgraph "Worker Pool State" |
| 272 | + WorkerPoolState["Worker Pool State"] |
| 273 | + subgraph WorkerPoolState |
| 249 274 | Available["MapSet<br/>⚡ O(1) member check<br/>⚡ O(1) add/remove"] |
| 250 275 | Busy["Map<br/>⚡ O(1) lookup"] |
| 251 276 | |
| @@ -255,7 +280,8 @@ graph LR | |
| 255 280 | BW4["Worker 4 🔴"] |
| 256 281 | end |
| 257 282 | |
| 258 | - subgraph "Load Distribution" |
| 283 | + LoadDistribution["Load Distribution"] |
| 284 | + subgraph LoadDistribution |
| 259 285 | Check{"Worker<br/>Available?"} |
| 260 286 | Assign["Assign to worker<br/>⚡ O(1)"] |
| 261 287 | Queue["Queue request<br/>⚡ O(1)"] |
| @@ -283,31 +309,39 @@ graph LR | |
| 283 309 | |
| 284 310 | Dequeue -->|Worker freed| Assign |
| 285 311 | |
| 286 | - style Q fill:#bbf,stroke:#333,stroke-width:4px,color:#000 |
| 287 | - style Available fill:#bfb,stroke:#333,stroke-width:4px,color:#000 |
| 288 | - style Check fill:#f9f,stroke:#333,stroke-width:4px,color:#000 |
| 312 | + style HighPerformanceRequestHandling fill:#e6e6fa,stroke:#9370db,stroke-width:3px,color:#2e1065 |
| 313 | + style RequestQueue fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 314 | + style WorkerPoolState fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 315 | + style LoadDistribution fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 316 | + style Q fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 317 | + style Available fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 318 | + style Check fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 289 319 | ``` |
| 290 320 | |
| 291 321 | ## 7. Process Registry - O(1) Performance |
| 292 322 | |
| 293 323 | ```mermaid |
| 294 324 | graph LR |
| 295 | - subgraph "Registry Architecture" |
| 296 | - subgraph "Worker Registry" |
| 325 | + RegistryArchitecture["Registry Architecture"] |
| 326 | + subgraph RegistryArchitecture |
| 327 | + WorkerRegistry["Worker Registry"] |
| 328 | + subgraph WorkerRegistry |
| 297 329 | WR["Elixir Registry<br/>⚡ :unique keys<br/>⚡ O(1) operations"] |
| 298 330 | WK1["worker_1 → PID1"] |
| 299 331 | WK2["worker_2 → PID2"] |
| 300 332 | WKN["worker_N → PIDN"] |
| 301 333 | end |
| 302 334 | |
| 303 | - subgraph "Process Registry (ETS)" |
| 335 | + ProcessRegistryETS["Process Registry ETS"] |
| 336 | + subgraph ProcessRegistryETS |
| 304 337 | PR["Process Registry<br/>⚡ :protected table<br/>⚡ read_concurrency"] |
| 305 338 | PK1["worker_1 → {pid, os_pid, fingerprint}"] |
| 306 339 | PK2["worker_2 → {pid, os_pid, fingerprint}"] |
| 307 340 | PKN["worker_N → {pid, os_pid, fingerprint}"] |
| 308 341 | end |
| 309 342 | |
| 310 | - subgraph "Starter Registry" |
| 343 | + StarterRegistry["Starter Registry"] |
| 344 | + subgraph StarterRegistry |
| 311 345 | SR["Starter Registry<br/>⚡ Supervisor tracking"] |
| 312 346 | SK1["worker_1 → Starter PID1"] |
| 313 347 | SK2["worker_2 → Starter PID2"] |
| @@ -315,7 +349,8 @@ graph LR | |
| 315 349 | end |
| 316 350 | end |
| 317 351 | |
| 318 | - subgraph "O(1) Operations" |
| 352 | + O1Operations["O(1) Operations"] |
| 353 | + subgraph O1Operations |
| 319 354 | Op1["via_tuple lookup<br/>⚡ Direct to worker"] |
| 320 355 | Op2["Reverse lookup<br/>⚡ PID to worker_id"] |
| 321 356 | Op3["OS PID tracking<br/>⚡ Cleanup guarantee"] |
| @@ -337,7 +372,12 @@ graph LR | |
| 337 372 | Op2 --> WR |
| 338 373 | Op3 --> PR |
| 339 374 | |
| 340 | - style WR fill:#bfb,stroke:#333,stroke-width:4px,color:#000 |
| 341 | - style PR fill:#bbf,stroke:#333,stroke-width:4px,color:#000 |
| 342 | - style SR fill:#fbf,stroke:#333,stroke-width:4px,color:#000 |
| 375 | + style RegistryArchitecture fill:#e6e6fa,stroke:#9370db,stroke-width:3px,color:#2e1065 |
| 376 | + style WorkerRegistry fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 377 | + style ProcessRegistryETS fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 378 | + style StarterRegistry fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 379 | + style O1Operations fill:#f3e8ff,stroke:#a855f7,stroke-width:2px,color:#581c87 |
| 380 | + style WR fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 381 | + style PR fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 382 | + style SR fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px,color:#581c87 |
| 343 383 | ``` |
| \ No newline at end of file |
| @@ -42,7 +42,7 @@ Snakepit is a battle-tested Elixir library that provides a robust pooling system | |
| 42 42 | # In your mix.exs |
| 43 43 | def deps do |
| 44 44 | [ |
| 45 | - {:snakepit, "~> 0.0.1"} |
| 45 | + {:snakepit, "~> 0.1.2"} |
| 46 46 | ] |
| 47 47 | end |
| 48 48 | |
| @@ -68,7 +68,7 @@ Application.put_env(:snakepit, :pool_config, %{pool_size: 4}) | |
| 68 68 | ```elixir |
| 69 69 | def deps do |
| 70 70 | [ |
| 71 | - {:snakepit, "~> 0.0.1"} |
| 71 | + {:snakepit, "~> 0.1.2"} |
| 72 72 | ] |
| 73 73 | end |
| 74 74 | ``` |
| @@ -1,6 +1,6 @@ | |
| 1 1 | {<<"links">>,[{<<"GitHub">>,<<"https://github.com/nshkrdotcom/snakepit">>}]}. |
| 2 2 | {<<"name">>,<<"snakepit">>}. |
| 3 | - {<<"version">>,<<"0.1.1">>}. |
| 3 | + {<<"version">>,<<"0.1.2">>}. |
| 4 4 | {<<"description">>, |
| 5 5 | <<"High-performance pooler and session manager for external language integrations">>}. |
| 6 6 | {<<"elixir">>,<<"~> 1.18">>}. |
| @@ -4,7 +4,7 @@ defmodule Snakepit.MixProject do | |
| 4 4 | def project do |
| 5 5 | [ |
| 6 6 | app: :snakepit, |
| 7 | - version: "0.1.1", |
| 7 | + version: "0.1.2", |
| 8 8 | elixir: "~> 1.18", |
| 9 9 | start_permanent: Mix.env() == :prod, |
| 10 10 | description: |