Skip to content

Improve WorkerThreadManager type inference #48

@zone117x

Description

@zone117x

The WorkerThreadManager implementation does not understand conditional return types for the .exec(...) function. Right now the type inference code extracts the args and response type separately, e.g.:

type WorkerPoolModuleInterface<TArgs extends unknown[], TResp> = {
  workerModule: NodeJS.Module;
  processTask: (...args: TArgs) => Promise<TResp> | TResp; // <-- any type interface involving both TArgs and TResp are broken here
}

declare class WorkerThreadManager<TArgs extends unknown[], TResp> {
  static init<TArgs extends unknown[], TResp>(workerModule: WorkerPoolModuleInterface<TArgs, TResp>, opts?: {
    workerCount?: number;
  }): Promise<WorkerThreadManager<TArgs, TResp>>;
  constructor(workerModule: WorkerPoolModuleInterface<TArgs, TResp>, opts?: {
    workerCount?: number;
  });
  exec(...args: TArgs): Promise<TResp>;
}

If the worker module defines conditional return types like the following, then the .exec(...) function incorrectly only allows the first possible input and output types.

type TaskArg =
  | { kind: 'block'; msg: CoreNodeNakamotoBlockMessage }
  | { kind: 'chunk'; msg: StackerDbChunk };

type TaskResult<T extends TaskArg> = T['kind'] extends 'block'
  ? { kind: 'block'; result: ReturnType<typeof parseNakamotoBlockMsg> }
  : { kind: 'chunk'; result: ReturnType<typeof parseStackerDbChunk> };

export function processTask<T extends TaskArg>(args: T): TaskResult<T> {
  if (args.kind === 'block') {
    return {
      kind: 'block',
      result: parseNakamotoBlockMsg(args.msg),
    } as TaskResult<T>;
  } else {
    return {
      kind: 'chunk',
      result: parseStackerDbChunk(args.msg),
    } as TaskResult<T>;
  }
}

Originally posted by @zone117x in hirosystems/signer-metrics-api#85 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions