Skip to content

fix: preserve shared earcut worker pool - #1248

Closed
MarkusTomio wants to merge 1 commit into
developmentseed:mainfrom
MarkusTomio:fix-shared-earcut-pool-lifecycle
Closed

fix: preserve shared earcut worker pool#1248
MarkusTomio wants to merge 1 commit into
developmentseed:mainfrom
MarkusTomio:fix-shared-earcut-pool-lifecycle

Conversation

@MarkusTomio

Copy link
Copy Markdown

This PR fixes an issue where recreating a polygon layer can terminate Lonboard's shared Earcut worker pool.

Lonboard passes one shared pool to the GeoArrow polygon layers. When a layer is disposed, GeoArrowSolidPolygonLayer.finalizeState() calls terminate() on the supplied pool. GeoArrowPolygonLayer is affected as well because it passes the pool to its GeoArrowSolidPolygonLayer fill sublayer. Subsequent polygon layers fail to queue triangulation work, because Lonboard reuses that same pool:

Cannot schedule pool tasks after terminate() has been called

I ran into this when rerunning a SolidPolygonLayer in Marimo: the first render worked, but recreating the layer caused the polygon fill to disappear until the page was reloaded. I could not reproduce the same behavior with the minimal example in JupyterLab.

Before

before_earcut_fix

After

after_earcut_fix

The change keeps the actual pool owned by Lonboard and exposes a wrapper that forwards the normal pool operations while making terminate() a no-op. This keeps the shared-pool behavior and prevents an individual GeoArrow layer from shutting it down.

Tested on current main (0.17.0-beta.1):

  • repeated polygon layer reruns now work
  • fill and auto_highlight continue to render correctly
  • the terminated-pool error no longer occurs
  • pnpm check, pnpm build, git diff --check pass

This fixes the issue on the Lonboard side. It may also be worth addressing the underlying ownership behavior upstream in GeoArrow.

@ds-release-bot ds-release-bot Bot added the fix label Aug 20, 2026
@kylebarron

Copy link
Copy Markdown
Member

Thanks for the issue/PR! This is indeed a bug.

When a layer is disposed, GeoArrowSolidPolygonLayer.finalizeState() calls terminate() on the supplied pool

I think this is the core problem. Here we see

  override async finalizeState(_context: LayerContext): Promise<void> {
    await this.state?.earcutWorkerPool?.terminate();
    console.log("terminated");
  }

while actually the SolidPolygonLayer should only terminate the worker pool if it created the pool

Let's create an issue there instead

@kylebarron

Copy link
Copy Markdown
Member

I created geoarrow/deck.gl-geoarrow#218. @MarkusTomio would you be interested in making a short PR there? Then we can release a new version of deck.gl-geoarrow and a new version of lonboard using it.

@kylebarron kylebarron closed this Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants