egametang/ET · critical · Exception
fiber local slot exhausted, zone: {zone}, nextLocalSlot: {lo
Error message
fiber local slot exhausted, zone: {zone}, nextLocalSlot: {localSlot}, dynamic range: [{FiberIdHelper.DynamicLocalSlotStart}, {FiberIdHelper.ReservedLocalSlotStart - 1}] What it means
AllocateLocalSlot (FiberManager line 200) throws when the dynamic local-slot counter for a zone reaches ReservedLocalSlotStart (int.MaxValue - 15). Slots are allocated per zone starting at DynamicLocalSlotStart (100000) and monotonically incremented; the code never recycles freed slots, so exhaustion implies an unbounded fiber-creation leak within one process lifetime.
Source
Thrown at Packages/cn.etetet.core/Scripts/Core/Share/World/Fiber/FiberManager.cs:200
catch (Exception e)
{
throw new Exception($"create fiber error: {fiberId} {sceneType}", e);
}
}
private int AllocateLocalSlot(int zone)
{
FiberIdHelper.ValidateZone(zone);
lock (this.localSlotLock)
{
int localSlot = this.nextLocalSlotByZone.TryGetValue(zone, out int nextLocalSlot)
? nextLocalSlot
: FiberIdHelper.DynamicLocalSlotStart;
if (localSlot >= FiberIdHelper.ReservedLocalSlotStart)
{
throw new Exception(
$"fiber local slot exhausted, zone: {zone}, nextLocalSlot: {localSlot}, dynamic range: [{FiberIdHelper.DynamicLocalSlotStart}, {FiberIdHelper.ReservedLocalSlotStart - 1}]");
}
this.nextLocalSlotByZone[zone] = localSlot + 1;
return localSlot;
}
}
/// <summary>
/// 创建纤程
/// </summary>
/// <param name="schedulerType">纤程调度器,-1: 主线程,-2: 当前线程,-3: 线程池, 其它: 纤程</param>
/// <param name="rootId"></param>
/// <param name="zone">区</param>
/// <param name="sceneType">场景类型</param>
/// <param name="name">纤程名称</param>
/// <param name="parent"></param>
/// <returns>纤程id</returns>View on GitHub (pinned to 5cab01f7a8)
Solutions
- Find and fix the fiber leak - ensure every CreateFiber has a matching Dispose/teardown and that no update loop spawns unbounded fibers.
- Pool/reuse fibers for repeated transient work instead of allocating new ones.
- If legitimate long-lived load needs many fibers, restart the process on a schedule (the slot space is per-process and not recycled).
- Add instrumentation counting live fibers per zone to detect the leak early.
Defensive patterns
Strategy: try-catch
Try / catch
try { return fiberManager.CreateFiber(...); }
catch (Exception e) when (e.Message.Contains("fiber local slot exhausted"))
{ Log.Error($"fiber slot exhaustion - likely fiber leak, restarting zone: {e}"); throw; } Prevention
- Always pair CreateFiber with teardown/Dispose.
- Never create fibers inside a per-frame/per-message loop without bounds.
- Pool transient fibers.
- Instrument live-fiber counts per zone and alert before exhaustion.
When it happens
Trigger: Creating more than ~2.1 billion fibers in a single zone (dynamic range 100000..int.MaxValue-16) without restart - effectively a runaway loop that spawns fibers and never disposes them, or fibers created in a hot loop without pooling.
Common situations: A server that repeatedly creates transient fibers per request/message without tearing them down, a reconnect storm, a bug creating a fiber inside an update loop, or an extremely long-lived process accumulating fibers.
Related errors
- location db manager not found scene: {root.Name}
- condition variable registry is not initialized
- zone: {zone} not found mongo connect string
- zone: {zone} not found mongo db name
- process fiber address not found, sceneType: {sceneType}
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/08131eadae88ea11.
Report an issue: GitHub.