Skip to content

Commit

Permalink
fix: Ember: code optimizations (#1010)
Browse files Browse the repository at this point in the history
* Ember: Code optimizations

* Fix & cleanup tests.
  • Loading branch information
Nerivec authored Apr 6, 2024
1 parent 328d0fd commit cd6906c
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 234 deletions.
24 changes: 5 additions & 19 deletions src/adapter/ember/adapter/emberAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -797,8 +797,6 @@ export class EmberAdapter extends Adapter {
private async initEzsp(): Promise<TsType.StartResult> {
let result: TsType.StartResult = "resumed";

await this.onNCPPreReset();

// NOTE: something deep in this call can throw too
const startResult = (await this.ezsp.start());

Expand All @@ -815,7 +813,6 @@ export class EmberAdapter extends Adapter {

// WARNING: From here on EZSP commands that affect memory allocation on the NCP should no longer be called (like resizing tables)

await this.onNCPPostReset();
await this.registerFixedEndpoints();
this.clearNetworkCache();

Expand All @@ -839,6 +836,10 @@ export class EmberAdapter extends Adapter {

logger.debug(`[INIT] Network Ready! ${JSON.stringify(this.networkCache)}`, NS);

this.watchdogCountersHandle = setInterval(this.watchdogCounters.bind(this), WATCHDOG_COUNTERS_FEED_INTERVAL);

this.requestQueue.startDispatching();

return result;
}

Expand Down Expand Up @@ -1502,22 +1503,6 @@ export class EmberAdapter extends Adapter {
}
}

/**
* Called right before a NCP reset.
*/
private async onNCPPreReset(): Promise<void> {
this.requestQueue.stopDispatching();
}

/**
* Called right after a NCP reset, right before the creation of endpoints.
*/
private async onNCPPostReset(): Promise<void> {
this.requestQueue.startDispatching();

this.watchdogCountersHandle = setInterval(this.watchdogCounters.bind(this), WATCHDOG_COUNTERS_FEED_INTERVAL);
}

//---- START Events

//---- END Events
Expand Down Expand Up @@ -2684,6 +2669,7 @@ export class EmberAdapter extends Adapter {
}

public async stop(): Promise<void> {
this.requestQueue.stopDispatching();
await this.ezsp.stop();

this.initVariables();
Expand Down
21 changes: 11 additions & 10 deletions src/adapter/ember/adapter/requestQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ export const NETWORK_DOWN_DEFER_MSEC = 1500;

export class EmberRequestQueue {
private readonly dispatchInterval: number;
/** Interval handler that manages `dispatch()` */
private dispatchHandler: NodeJS.Timeout;
/** If true, the queue is currently busy dispatching. */
private dispatching: boolean;
/** The queue holding requests to be sent. */
Expand All @@ -49,7 +47,7 @@ export class EmberRequestQueue {
* Prevent sending requests (usually due to NCP being reset).
*/
public stopDispatching(): void {
clearInterval(this.dispatchHandler);
this.dispatching = false;

logger.debug(`Dispatching stopped; queue=${this.queue.length} priorityQueue=${this.priorityQueue.length}`, NS);
}
Expand All @@ -59,7 +57,9 @@ export class EmberRequestQueue {
* Must be called after init.
*/
public startDispatching(): void {
this.dispatchHandler = setInterval(this.dispatch.bind(this), this.dispatchInterval);
this.dispatching = true;

setTimeout(this.dispatch.bind(this), 0);

logger.debug(`Dispatching started.`, NS);
}
Expand Down Expand Up @@ -96,8 +96,8 @@ export class EmberRequestQueue {
*
* WARNING: Because of this logic for "internal retries", any error thrown by `func` will not immediatedly bubble back to Adapter/Controller
*/
public async dispatch(): Promise<void> {
if (this.dispatching) {
private async dispatch(): Promise<void> {
if (!this.dispatching) {
return;
}

Expand All @@ -110,7 +110,6 @@ export class EmberRequestQueue {
}

if (entry) {
this.dispatching = true;
entry.sendAttempts++;

// NOTE: refer to `enqueue()` comment to keep logic in sync with expectations, adjust comment on change.
Expand Down Expand Up @@ -142,17 +141,19 @@ export class EmberRequestQueue {
(fromPriorityQueue ? this.priorityQueue : this.queue).shift();
entry.reject(err);
}
} finally {
this.dispatching = false;
}
}

if (this.dispatching) {
setTimeout(this.dispatch.bind(this), this.dispatchInterval);
}
}

/**
* Defer dispatching for the specified duration (in msec).
* @param msec
*/
public defer(msec: number): void {
private defer(msec: number): void {
this.stopDispatching();

setTimeout(this.startDispatching.bind(this), msec);
Expand Down
35 changes: 13 additions & 22 deletions src/adapter/ember/ezsp/ezsp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,11 @@ export class Ezsp extends EventEmitter {
}

private initVariables(): void {
clearInterval(this.tickHandle);
if (this.waitingForResponse) {
clearTimeout(this.responseWaiter.timer);
}

clearTimeout(this.tickHandle);

this.frameContents.fill(0);
this.frameLength = 0;
Expand Down Expand Up @@ -353,7 +357,7 @@ export class Ezsp extends EventEmitter {

if (status === EzspStatus.SUCCESS) {
logger.info(`======== EZSP started ========`, NS);
this.registerHandlers();
this.tick();
return status;
}
}
Expand All @@ -368,12 +372,6 @@ export class Ezsp extends EventEmitter {
public async stop(): Promise<void> {
await this.ash.stop();

if (this.waitingForResponse) {
clearTimeout(this.responseWaiter.timer);
}

clearInterval(this.tickHandle);

this.initVariables();
logger.info(`======== EZSP stopped ========`, NS);
}
Expand Down Expand Up @@ -439,27 +437,19 @@ export class Ezsp extends EventEmitter {
}
}

private registerHandlers(): void {
this.tickHandle = setInterval(this.tick.bind(this), this.tickInterval);
}

/**
* The Host application must call this function periodically to allow the EZSP layer to handle asynchronous events.
*/
private tick(): void {
if (this.sendingCommand) {
// don't process any callbacks while expecting a command's response
return;
}

// don't process any callbacks while sending a command and waiting for its response
// nothing in the rx queue, nothing to receive
if (this.ash.rxQueue.empty) {
return;
if (!this.sendingCommand && !this.ash.rxQueue.empty) {
if (this.responseReceived() === EzspStatus.SUCCESS) {
this.callbackDispatch();
}
}

if (this.responseReceived() === EzspStatus.SUCCESS) {
this.callbackDispatch();
}
this.tickHandle = setTimeout(this.tick.bind(this), this.tickInterval);
}

private nextFrameSequence(): number {
Expand Down Expand Up @@ -2054,6 +2044,7 @@ export class Ezsp extends EventEmitter {
*/
ezspCounterRolloverHandler(type: EmberCounterType): void {
logger.debug(`ezspCounterRolloverHandler(): callback called with: [type=${EmberCounterType[type]}]`, NS);
logger.info(`NCP Counter ${EmberCounterType[type]} rolled over.`, NS);
}

/**
Expand Down
Loading

0 comments on commit cd6906c

Please sign in to comment.