Skip to content

Commit

Permalink
feat(channel): Add processCommand method that never reject command er…
Browse files Browse the repository at this point in the history
…rors and pass this response to
  • Loading branch information
Samuel Martins da Silva committed Sep 20, 2019
1 parent 24b28b3 commit 24f32b0
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
48 changes: 47 additions & 1 deletion src/Lime/Protocol/Client/Channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Command, { CommandListener, CommandMethod, CommandStatus } from "../Comma
import Notification, { NotificationListener, NotificationEvent } from "../Notification";
import Session, { SessionListener, SessionState } from "../Session";
import Transport from "../Network/Transport";
import * as Promise from "bluebird";

export interface MessageChannel extends MessageListener {
sendMessage(message: Message): void;
Expand All @@ -21,16 +22,23 @@ export interface SessionChannel extends SessionListener {
sendSession(session: Session): void;
}

abstract class Channel implements MessageChannel, CommandChannel, NotificationChannel, SessionChannel {
export interface ProcessCommand extends CommandListener {
processCommand(command: Command): void;
}

abstract class Channel implements MessageChannel, CommandChannel, NotificationChannel, SessionChannel, ProcessCommand {

private autoReplyPings: boolean;
private autoNotifyReceipt: boolean;

commandTimeout = 6000;

transport: Transport;
remoteNode: string;
localNode: string;
sessionId: string;
state: SessionState;
_commandResolves: {};

constructor(transport: Transport, autoReplyPings: boolean, autoNotifyReceipt: boolean) {
this.autoReplyPings = autoReplyPings;
Expand Down Expand Up @@ -86,6 +94,35 @@ abstract class Channel implements MessageChannel, CommandChannel, NotificationCh
}
abstract onMessage(message: Message): void;

processCommand(command: Command, timeout = this.commandTimeout): Promise<Command> {
const commandPromise = Promise.race([
new Promise((resolve) => {
this._commandResolves[command.id] = c => {
if (!c.status) return

resolve(c)

delete this._commandResolves[command.id]
}
}),
new Promise((_, reject) => {
setTimeout(() => {
if (!this._commandResolves[command.id]) return

delete this._commandResolves[command.id]
command.status = 'failure'
command.timeout = true

const cmd = JSON.stringify(command)
reject(new ClientError(cmd))
}, timeout)
})
])

this.sendCommand(command)
return commandPromise
}

sendCommand(command: Command) {
if (this.state !== SessionState.ESTABLISHED) {
throw new Error(`Cannot send in the '${this.state}' state`);
Expand Down Expand Up @@ -135,4 +172,13 @@ abstract class Channel implements MessageChannel, CommandChannel, NotificationCh
}
}

class ClientError extends Error {
constructor(message) {
super();

this.name = '';
this.message = message;
}
}

export default Channel;
1 change: 1 addition & 0 deletions src/Lime/Protocol/Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface Command extends Envelope {
method: CommandMethod;
status?: CommandStatus;
reason?: Reason;
timeout?: boolean;
}
export default Command;

Expand Down

0 comments on commit 24f32b0

Please sign in to comment.