Skip to content

Root context factory indirection #79

@casimiro

Description

@casimiro

Hello,

I noticed the SDK expects registerRootContext to receive a name parameter that's used as a key to store context_factory in the global map root_context_factory_map:

let root_context_factory_map = new Map<string, (context_id: u32) => RootContext>();
// ...
export function registerRootContext(
  root_context_factory: (context_id: u32) => RootContext,
  name: string): void {
  root_context_factory_map.set(name, root_context_factory);
}

When the host application creates the root context for the filter it calls proxy_on_context_create, which invokes ensureRootContext:

export function ensureRootContext(root_context_id: u32): RootContext {
  log(LogLevelValues.debug, "ensureRootContext(root_context_id: " + root_context_id.toString() + ")");
  log(LogLevelValues.debug, "Current context_map: " + context_map.keys().join(", "));
  if (context_map.has(root_context_id)) {
    log(LogLevelValues.debug, "Returning root context for id: " + root_context_id.toString());
    return getRootContext(root_context_id);
  }
  const root_id = get_plugin_root_id();
  log(LogLevelValues.debug, "Registering new root context for " + root_id + " with id: " + root_context_id.toString());
  if (!root_context_factory_map.has(root_id)) {
    throw new Error("Missing root context factory for root id: " + root_id);
  }
  const root_context_func = root_context_factory_map.get(root_id);
  const root_context = root_context_func(root_context_id);
  root_context.context_id = root_context_id;
  context_map.set(root_context_id, root_context);
  return root_context;
}

ensureRootContext calls get_plugin_root_id() (i.e., get_property("plugin_root_id") expecting it to return the name of the filter as it's set in envoy configuration file. It then uses this value to retrieve the context factory from root_context_factory_map which is then used to build the root context that's later returned.

It's not clear to me, however, the necessity of storing the root context factory in a map. Why can't it be stored directly in a variable, e.g. let root_context_factory: (context_id: u32) => RootContext;?

Does the SDK expect filters to implement more than one root context factory? Is there a use case requiring multiple root contexts?

I stumble upon this behaviour while trying to run the addHeader example filter on ngx_wasm_module which returns a numeric value for the property plugin_root_id -- instead of the expected addHeader value.

If the authors agree this indirection can be safely removed, I'm happy to open a PR with a patch that removes it while keeping registerRootContext compatible with existing filters.

Thank you for working on this proxy-wasm SDK.

Kind regards,
Caio.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions