Skip to content

Commit

Permalink
pair programming: required fixes found when rebuilding sample app
Browse files Browse the repository at this point in the history
Signed-off-by: Amber Torrise <at895452@broadcom.net>
  • Loading branch information
Amber Torrise committed May 13, 2024
1 parent 423455b commit ee56384
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 23 deletions.
22 changes: 13 additions & 9 deletions packages/imperative/src/events/src/EventEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ConfigUtils } from "../../config/src/ConfigUtils";
import { LoggerManager } from "../../logger/src/LoggerManager";
import { ImperativeConfig } from "../../utilities";
import { EventUtils } from "./EventUtils";
import { IRegisteredAction } from "./doc";

/**
* The EventEmitter class is responsible for managing event subscriptions and emissions for a specific application.
Expand All @@ -26,7 +27,7 @@ import { EventUtils } from "./EventUtils";
* @class EventEmitter
*/
export class EventEmitter {
public events: Map<string, Event> = new Map();
public subscribedEvents: Map<string, Event> = new Map();
public eventTimes: Map<string, string>;
public appName: string;
public logger: Logger;
Expand All @@ -38,7 +39,7 @@ export class EventEmitter {
* @param {Logger} logger The logger instance used for logging information and errors.
*/
public constructor(appName: string, logger?: Logger) {
this.events = new Map();
this.subscribedEvents = new Map();
this.appName = appName;

// Ensure we have correct environmental conditions to setup a custom logger,
Expand All @@ -58,22 +59,25 @@ export class EventEmitter {
*
* @param {string} eventName
*/
public subscribeShared(eventName: string): void {
public subscribeShared(eventName: string, callbacks: Function[] | Function): IRegisteredAction {
const isCustom = EventUtils.isSharedEvent(eventName);

Check warning on line 63 in packages/imperative/src/events/src/EventEmitter.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventEmitter.ts#L62-L63

Added lines #L62 - L63 were not covered by tests
const eventType = isCustom ? EventTypes.CustomSharedEvents : EventTypes.SharedEvents;
EventUtils.createSubscription(this, eventName, eventType);
const disposable = EventUtils.createSubscription(this, eventName, eventType);
EventUtils.setupWatcher(this, eventName, callbacks);
return disposable;

Check warning on line 67 in packages/imperative/src/events/src/EventEmitter.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventEmitter.ts#L65-L67

Added lines #L65 - L67 were not covered by tests
}

/**
* Subscribes to a user event. This method determines whether the event is custom and creates a subscription accordingly.
*
* @param {string} eventName
*/
public subscribeUser(eventName: string, callbacks: Function[]): void {
public subscribeUser(eventName: string, callbacks: Function[] | Function): IRegisteredAction {
const isCustom = EventUtils.isUserEvent(eventName);

Check warning on line 76 in packages/imperative/src/events/src/EventEmitter.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventEmitter.ts#L75-L76

Added lines #L75 - L76 were not covered by tests
const eventType = isCustom ? EventTypes.CustomUserEvents : EventTypes.UserEvents;
EventUtils.createSubscription(this, eventName, eventType);
const disposable = EventUtils.createSubscription(this, eventName, eventType);
EventUtils.setupWatcher(this, eventName, callbacks);
return disposable;

Check warning on line 80 in packages/imperative/src/events/src/EventEmitter.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventEmitter.ts#L78-L80

Added lines #L78 - L80 were not covered by tests
}

/**
Expand All @@ -85,7 +89,7 @@ export class EventEmitter {
*/
public emitEvent(eventName: string): void {
try {
const event = this.events.get(eventName);
const event = this.subscribedEvents.get(eventName);
event.eventTime = new Date().toISOString();
EventUtils.writeEvent(event);

Check warning on line 94 in packages/imperative/src/events/src/EventEmitter.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventEmitter.ts#L90-L94

Added lines #L90 - L94 were not covered by tests
} catch (err) {
Expand All @@ -103,10 +107,10 @@ export class EventEmitter {
public unsubscribe(eventName: string): void {
try{

Check warning on line 108 in packages/imperative/src/events/src/EventEmitter.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventEmitter.ts#L107-L108

Added lines #L107 - L108 were not covered by tests
// find watcher list and close everything
this.events.get(eventName).subscriptions.forEach((watcher)=>{
this.subscribedEvents.get(eventName).subscriptions.forEach((watcher)=>{
watcher.removeAllListeners(eventName).close();

Check warning on line 111 in packages/imperative/src/events/src/EventEmitter.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventEmitter.ts#L110-L111

Added lines #L110 - L111 were not covered by tests
});
this.events.delete(eventName);
this.subscribedEvents.delete(eventName);

Check warning on line 113 in packages/imperative/src/events/src/EventEmitter.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventEmitter.ts#L113

Added line #L113 was not covered by tests
} catch(err){
throw new ImperativeError({ msg: `Error unsubscribing from event: ${eventName}`, causeErrors: err });

Check warning on line 115 in packages/imperative/src/events/src/EventEmitter.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventEmitter.ts#L115

Added line #L115 was not covered by tests
}
Expand Down
4 changes: 2 additions & 2 deletions packages/imperative/src/events/src/EventEmitterManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ export class EventEmitterManager {
*
* @static
* @param {string} appName key to KVP for managed event emitter instances
* @return {(EventEmitter | undefined)} Returns the EventEmitter instance or undefined if it cannot be created.
* @return {EventEmitter} Returns the EventEmitter instance
*/
public static getEmitter(appName: string): EventEmitter | undefined {
public static getEmitter(appName: string): EventEmitter {

Check warning on line 32 in packages/imperative/src/events/src/EventEmitterManager.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventEmitterManager.ts#L32

Added line #L32 was not covered by tests
if (!this.instances.has(appName)) {
const newInstance = new EventEmitter(appName);
this.instances.set(appName, newInstance);

Check warning on line 35 in packages/imperative/src/events/src/EventEmitterManager.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventEmitterManager.ts#L34-L35

Added lines #L34 - L35 were not covered by tests
Expand Down
42 changes: 30 additions & 12 deletions packages/imperative/src/events/src/EventUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/

import { ImperativeError } from "../../error/src/ImperativeError";
import { dirname, join } from "path";
import { join } from "path";
import { UserEvents, SharedEvents, EventTypes } from "./EventConstants";
import * as fs from "fs";
import { ConfigUtils } from "../../config/src/ConfigUtils";
Expand Down Expand Up @@ -48,7 +48,7 @@ export class EventUtils {
}

/**
* Retrieves the directory path for events based on the event type and application name.
* Modifies path to include appName if a custom event type
*
* @param {EventTypes} eventType
* @param {string} appName
Expand All @@ -75,6 +75,20 @@ export class EventUtils {
}
}

/**
* Check to see if the file path exists, otherwise, create it : )
* @param filePath Zowe or User path where we will write the events
*/
public static ensureFileExists(filePath: string) {
try {

Check warning on line 83 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L82-L83

Added lines #L82 - L83 were not covered by tests
if (!fs.existsSync(filePath)) {
fs.closeSync(fs.openSync(filePath, 'w'));

Check warning on line 85 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L85

Added line #L85 was not covered by tests
}
} catch (err) {
throw new ImperativeError({ msg: `Unable to create event file. Path: ${filePath}`, causeErrors: err });

Check warning on line 88 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L88

Added line #L88 was not covered by tests
}
}

/**
* Creates a subscription for an event. It configures and stores an event instance within the EventEmitter's subscription map.
*
Expand All @@ -85,8 +99,11 @@ export class EventUtils {
*/
public static createSubscription(eeInst: EventEmitter, eventName: string, eventType: EventTypes): IRegisteredAction {
const dir = this.getEventDir(eventType, eeInst.appName);
this.ensureEventsDirExists(dir);
const filePath = join(dirname(ConfigUtils.getZoweDir()), eventName);
this.ensureEventsDirExists(join(ConfigUtils.getZoweDir(), '.events'));
this.ensureEventsDirExists(join(ConfigUtils.getZoweDir(), dir));

Check warning on line 103 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L100-L103

Added lines #L100 - L103 were not covered by tests

const filePath = join(ConfigUtils.getZoweDir(), dir, eventName);
this.ensureFileExists(filePath);

Check warning on line 106 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L105-L106

Added lines #L105 - L106 were not covered by tests

const newEvent = new Event({

Check warning on line 108 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L108

Added line #L108 was not covered by tests
eventTime: new Date().toISOString(),
Expand All @@ -97,22 +114,25 @@ export class EventUtils {
subscriptions: []
});

eeInst.events.set(eventName, newEvent);
eeInst.subscribedEvents.set(eventName, newEvent);

Check warning on line 117 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L117

Added line #L117 was not covered by tests

return {
close: () => eeInst.unsubscribe(eventName)

Check warning on line 120 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L119-L120

Added lines #L119 - L120 were not covered by tests
};
}

public static setupWatcher(eeInst: EventEmitter, eventName: string, callbacks: Function[] = []): fs.FSWatcher {
const event = eeInst.events.get(eventName);
public static setupWatcher(eeInst: EventEmitter, eventName: string, callbacks: Function[] | Function ): fs.FSWatcher {
const event = eeInst.subscribedEvents.get(eventName);
const watcher = fs.watch(event.filePath, (trigger: "rename" | "change") => {

Check warning on line 126 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L124-L126

Added lines #L124 - L126 were not covered by tests
// Accommodates for the delay between actual file change event and fsWatcher's perception
//(Node.JS triggers this notification event 3 times)
if (eeInst.eventTimes.get(eventName) !== event.eventTime) {
eeInst.logger.debug(`EventEmitter: Event "${trigger}" emitted: ${eventName}`);

Check warning on line 130 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L130

Added line #L130 was not covered by tests
// Promise.all(callbacks)
callbacks.forEach(cb => cb());
if (Array.isArray(callbacks)){
callbacks.forEach(cb => cb());
}else {
callbacks();

Check warning on line 134 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L132-L134

Added lines #L132 - L134 were not covered by tests
}
eeInst.eventTimes.set(eventName, event.eventTime);

Check warning on line 136 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L136

Added line #L136 was not covered by tests
}
});
Expand All @@ -126,8 +146,6 @@ export class EventUtils {
* @param {Event} event
*/
public static writeEvent(event: Event) {
const eventPath = join(ConfigUtils.getZoweDir(), event.filePath);
this.ensureEventsDirExists(eventPath);
fs.writeFileSync(eventPath, JSON.stringify(event.toJson(), null, 2));
fs.writeFileSync(event.filePath, JSON.stringify(event.toJson(), null, 2));

Check warning on line 149 in packages/imperative/src/events/src/EventUtils.ts

View check run for this annotation

Codecov / codecov/patch

packages/imperative/src/events/src/EventUtils.ts#L148-L149

Added lines #L148 - L149 were not covered by tests
}
}

0 comments on commit ee56384

Please sign in to comment.