Race Conditions
Sdílený měnitelný stav vede k nepředvídatelným chybám
|
Vytvářejte odolné, škálovatelné systémy v TypeScriptu
Běžné problémy, které zpomalují vývoj a způsobují produkční incidenty
Sdílený měnitelný stav vede k nepředvídatelným chybám
Jedna chyba může shodit celou aplikaci
Distribuované systémy jsou obtížné na správné nastavení
noex tyto problémy řeší
Osvědčené vzory z Erlang/OTP, přepracované pro TypeScript
Stavové procesy bez race conditions. Sekvenční zpracování zpráv garantuje konzistenci.
class Counter extends GenServer {
init() { return 0; }
handleCall(msg: 'get') {
return this.state;
}
handleCast(msg: 'inc') {
this.state++;
}
} Automatický restart při selhání. Filozofie 'nech to spadnout' s chytrými strategiemi obnovy.
const supervisor = new Supervisor({
children: [
{ id: 'counter', start: () => Counter },
{ id: 'cache', start: () => Cache }
],
strategy: 'one_for_one',
maxRestarts: 3
});Vyhledávání procesů podle jména. Najděte procesy pomocí názvu místo správy referencí.
// Register a process
Registry.register('user:123', userProcess);
// Find it anywhere
const user = Registry.lookup('user:123');
await user.call({ type: 'getProfile' });Produkčně připravené utility, které bezproblémově spolupracují s vašimi procesy
In-memory cache s TTL a automatickým čištěním
// Cache with TTL
const cache = new Cache({ ttl: 60_000 });
await cache.set('user:123', userData);
const user = await cache.get('user:123');
// Auto-cleanup on expirationPublish/subscribe messaging mezi procesy
// Pub/sub messaging
const bus = new EventBus();
bus.subscribe('order:created', async (order) => {
await sendConfirmation(order);
});
bus.publish('order:created', newOrder);Token bucket rate limiting pro API a zdroje
// Token bucket rate limiting
const limiter = new RateLimiter({
tokens: 100,
interval: 60_000
});
if (await limiter.acquire('api:user:123')) {
// Process request
}Monitorujte své procesy v reálném čase bez jakékoli konfigurace
┌─ Process Tree ────────────────┐ ┌─ Stats Table ─────────────────────────────────────┐│ ▼ supervisor:main │ │ ID │ Status │ Msgs │ Mem │ Up ││ ├─ ● counter (running) │ │─────────────────┼─────────┼──────┼────────┼───────││ ├─ ● cache (running) │ │ counter │ running │ 1.2k │ 2.4 MB │ 01:23 ││ ├─ ● rate-limiter (running) │ │ cache │ running │ 847 │ 12 MB │ 01:23 ││ └─ ● event-bus (running) │ │ rate-limiter │ running │ 156 │ 1.1 MB │ 01:23 ││ │ │ event-bus │ running │ 2.1k │ 3.2 MB │ 01:23 │└───────────────────────────────┘ └───────────────────────────────────────────────────┘┌─ Memory ──────────────────────┐ ┌─ Event Log ───────────────────────────────────────┐│ ████████░░░░░ │ │ [12:34:56] ✓ GenServer started: counter ││ 67% / 256MB │ │ [12:34:57] ✓ GenServer started: cache ││ │ │ [12:34:58] ℹ Supervisor: main (4 children) │└───────────────────────────────┘ └───────────────────────────────────────────────────┘ [q]uit [r]efresh [?]help [1-3]layout │ Processes: 4 │ Up: 00:01:23npx @hamicek/noex dashboardWebové rozhraní pro vzdálený monitoring
Interaktivní terminálový dashboard s klávesovou navigací
CPU, paměť a propustnost zpráv v reálném čase
Události s časovými razítky a úrovní závažnosti
Škálujte napříč stroji s transparentní lokací. Vaše procesy fungují stejně na jednom stroji i na stovkách.
Uzly se automaticky objevují pomocí mDNS nebo seed nodů. Žádný centrální koordinátor není potřeba.
Registrujte a vyhledávejte procesy napříč všemi uzly podle jména. Jedno API pro lokální i vzdálené procesy.
Posílejte zprávy procesům bez ohledu na jejich fyzické umístění. Runtime se postará o routování.
// Register a process globally
await GlobalRegistry.register('user:session:123', pid);
// Find it from any node in the cluster
const pid = await GlobalRegistry.whereis('user:session:123');
// Send a message - works across nodes
await GenServer.call(pid, { type: 'get_data' });Stejné API pro lokální i vzdálené procesy
Prozkoumejte reálné příklady a uvidíte noex v akci
import { GenServer, Supervisor, Registry } from class=class="hl-string">"hl-string">'@hamicek/noex';
class Counter extends GenServer {
init() {
return 0;
}
handleCall(msg: { type: class=class="hl-string">"hl-string">'get' }) {
return this.state;
}
handleCast(msg: { type: class=class="hl-string">"hl-string">'increment' } | { type: class=class="hl-string">"hl-string">'decrement' }) {
if (msg.type === class=class="hl-string">"hl-string">'increment') {
this.state++;
} else {
this.state--;
}
}
}
class=class="hl-string">"hl-comment">// Start the counter
const counter = await Counter.start();
class=class="hl-string">"hl-comment">// Interact with it
await counter.cast({ type: class=class="hl-string">"hl-string">'increment' });
await counter.cast({ type: class=class="hl-string">"hl-string">'increment' });
const value = await counter.call({ type: class=class="hl-string">"hl-string">'get' });
console.log(class=class="hl-string">"hl-string">'Counter value:', value); Začněte za pár minut jednoduchou instalací přes npm
$ npm install @hamicek/noex npm install @hamicek/noeximport { GenServer } from '@hamicek/noex'await Counter.start()import { GenServer } from class=class="hl-string">"hl-string">'@hamicek/noex';
class Counter extends GenServer {
init() { return 0; }
handleCast(msg: class=class="hl-string">"hl-string">'inc') {
this.state++;
}
}
const counter = await Counter.start(); Líbí se vám noex? Pomozte nám pokračovat ve vývoji