• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rokucommunity / roku-debug / 26120672946

19 May 2026 07:37PM UTC coverage: 70.727% (+0.7%) from 70.049%
26120672946

Pull #351

github

web-flow
Merge eb0b2e542 into 5bbd82240
Pull Request #351: 0.23.8

3328 of 5046 branches covered (65.95%)

Branch coverage included in aggregate %.

5834 of 7908 relevant lines covered (73.77%)

35.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

14.29
/src/bsc/threading/ThreadRunner.ts
1
import type { MessagePort } from 'worker_threads';
2
import type { MethodNames, WorkerMessage } from './ThreadMessageHandler';
2✔
3
import { ThreadMessageHandler } from './ThreadMessageHandler';
2✔
4

2✔
5
/**
6
 * Runner logic for Running a Project in a worker thread.
7
 */
8
export class ThreadRunner<T extends ThreadRunnerSubject> {
9

10
    public constructor(
×
11
        private subjectFactory: () => T
12
    ) {
×
13

14
    }
15

×
16
    //collection of interceptors that will be called when events are fired
17
    private requestInterceptors = {} as Record<MethodNames<T>, (data: any) => any>;
18

19
    /**
20
     * The instance of the object this runner will communicate with. It should have methods with the same names as the request being sent.
×
21
     */
22
    private subject: T;
×
23

24
    private messageHandler: ThreadMessageHandler<T>;
×
25

×
26
    public run(parentPort: MessagePort) {
27
        this.messageHandler = new ThreadMessageHandler({
28
            name: 'WorkerThread',
29
            port: parentPort,
×
30
            onRequest: async (request: WorkerMessage) => {
×
31
                try {
32
                    //if we have a request interceptor registered for this event, call it
33
                    this.requestInterceptors[request.name]?.(request.data);
34

35
                    //only the LspProject interface method names will be passed as request names, so just call those functions on the Project class directly
36
                    let responseData = await this.subject[request.name](...request.data ?? []);
×
37
                    this.messageHandler.sendResponse(request, { data: responseData });
38

39
                    //we encountered a runtime crash. Pass that error along as the response to this request
40
                } catch (e) {
41
                    const error: Error = e as unknown as any;
42
                    this.messageHandler.sendResponse(request, { error: error });
43
                }
44
            },
×
45
            onUpdate: (update) => {
46

×
47
            }
48
        });
49

2✔
50
        (this.requestInterceptors as any).activate = this.onActivate.bind(this);
51
    }
52

53
    /**
54
     * Fired anytime we get an `activate` request from the client. This allows us to clean up the previous project and make a new one
55
     */
56
    private onActivate() {
57
        //clean up any existing project
58
        void this.subject?.dispose();
59

60
        //make a new instance of the subject
61
        this.subject = this.subjectFactory();
62
    }
63
}
64

65
export interface ThreadRunnerSubject {
66
    /**
67
     * Called whenever a new subject has been activated
68
     */
69
    activate(...args: any[]): void | Promise<any>;
70
    /**
71
     * Called whenever a subject will no longer be used. Allows for cleaning up a subject.
72
     */
73
    dispose(): void | Promise<any>;
74
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc