Skip to content

Commit

Permalink
Merge pull request #45 from ainize-team/feat/woojae/handler
Browse files Browse the repository at this point in the history
Feat/woojae/handler
  • Loading branch information
akastercomcom authored Sep 19, 2023
2 parents 766c2b8 + 952e231 commit c409c54
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 120 deletions.
5 changes: 5 additions & 0 deletions src/ain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,9 @@ export default class AinModule {
this.isDefaultAccountExist();
return this.ain!.wallet.defaultAccount!.address;
}

getEventManager() {
this.checkAinInitiated();
return this.ain!.em;
}
}
2 changes: 0 additions & 2 deletions src/ainize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ export default class Ainize {
private cache: NodeCache;
ain: Ain;
middleware: Middleware;
handler: Handler;
appController: AppController = AppController.getInstance();

constructor(chainId: 1 | 0) {
const blockChainEndpoint = getBlockChainEndpoint(chainId);
this.ain = new Ain(blockChainEndpoint, chainId);
this.cache = new NodeCache();
this.middleware = new Middleware(this.cache);
this.handler = new Handler(this);
}

// FIXME(yoojin): add config type and change param type.
Expand Down
21 changes: 13 additions & 8 deletions src/controllers/modelController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import AinModule from "../ain";
import { Path } from "../constants";
import { getRequestDepositOp, getTransferOp } from "../utils/operator";
import { buildSetOperation, buildTxBody } from "../utils/builder";
import Handler from "../handlers/handler";

export default class ModelController {
private static instance: ModelController | undefined;
private ain = AinModule.getInstance();
private handler = Handler.getInstance();
static getInstance() {
if(!ModelController.instance){
ModelController.instance = new ModelController();

}
return ModelController.instance;
}
Expand Down Expand Up @@ -73,13 +74,17 @@ export default class ModelController {
//TODO(woojae): connect with handler
async use(modelName: string, requestData: string) {
this.isLoggedIn();
const requestKey = Date.now();
const requesterAddress = this.ain.getAddress();
const requestPath = Path.app(modelName).request(requesterAddress, requestKey);
const requestOp = buildSetOperation("SET_VALUE", requestPath, {prompt: requestData});
const txBody = buildTxBody(requestOp);
await this.ain.sendTransaction(txBody);
return requestKey;
const result = await new Promise(async (resolve, reject) => {
const requestKey = Date.now();
const requesterAddress = this.ain.getAddress();
await this.handler.subscribe(requesterAddress, requestKey.toString(), modelName, resolve);
const requestPath = Path.app(modelName).request(requesterAddress, requestKey);
const requestOp = buildSetOperation("SET_VALUE", requestPath, {prompt: requestData});
const txBody = buildTxBody(requestOp);
await this.ain.sendTransaction(txBody);
return requestKey;
});
return result;
}

//TODO(woojae): implement this
Expand Down
101 changes: 37 additions & 64 deletions src/handlers/handler.ts
Original file line number Diff line number Diff line change
@@ -1,94 +1,67 @@
const _ = require("lodash");
import Ain from "@ainblockchain/ain-js";
import { HANDLER_HEARBEAT_INTERVAL, Path } from "../constants";
import Ainize from "../ainize";
import { Path } from "../constants";
import AinModule from "../ain";
import EventManager from "@ainblockchain/ain-js/lib/event-manager";

export default class Handler {
isConnected: boolean = false;
subscribeTable:any = {};
ain: Ain;
constructor(ainize: Ainize) {
this.ain = ainize.ain;
private static instance: Handler | undefined;
em = AinModule.getInstance().getEventManager();
static getInstance() {
if(!Handler.instance){
Handler.instance = new Handler();
}
return Handler.instance;
}

checkEventManager() {
if (!this.em) {
if(!AinModule.getInstance().getEventManager()){
throw new Error('you should init ain first');
}
this.em = AinModule.getInstance().getEventManager();
}
return true;
}

/**
* Connect to ai Network event node. you should connect before subscibe. It will auto reconnect when disconnected.
* @returns Nothing.
*/
async connect() {
await this.ain.em.connect({}, this.disconnectedCallback.bind(this));
this.isConnected = true;
this.checkEventManager();
await this.em!.connect({},this.disconnectedCb);
console.log('connected');
};

private async disconnectedCallback() {
this.isConnected = false;
private async disconnectedCb() {
console.log('disconnected. reconnecting...');
await this.connect();
}

/**
* Subscribe to specific service reponse. You can handle reponse with callback function.
* You should connect before subscibe.
* @param {string} userAddress - Address of account you request with.
* @param {string} appName - App name you want to subscribe.
* @param {Function(valueChangedEvent: any)} callback - A callback function to handle response. It will be called when response is written.
* @returns SubscribeId.
*/
async subscribe(userAddress:string, appName: string, callback: (valueChangedEvent: any) => any) {
if (this.checkSubscribeTableExists(userAddress, appName)){
throw new Error("Already subscribed");
}
const subscribeId = await this.ain.em.subscribe(
async subscribe(requester:string, recordId:string, appName: string, resolve: any) {
this.checkEventManager();
const responsePath = Path.app(appName).response(requester, recordId);
const subscribeId = await this.em!.subscribe(
"VALUE_CHANGED",
{
path: Path.app(appName).response(userAddress, "$requestKey"),
path: responsePath,
event_source: "USER",
},
(valueChangedEvent) => {
callback(valueChangedEvent);
(valueChangedEvent: any) => {
this.unsubscribe(subscribeId);
resolve(valueChangedEvent.values.after.data);
},
(err) => {
throw new Error(err.message);
},
);
this.addToSubscribeTable(userAddress, appName, subscribeId);
return subscribeId;
}

private checkSubscribeTableExists(userAddress:string, appName:string,) {
return _.has(this.subscribeTable, [userAddress, appName]);
}

private addToSubscribeTable(userAddress:string, appName: string, filterId: string) {
_.set(this.subscribeTable, [userAddress], {appName:filterId});
}

/**
* Get subscribe list of userAddress. If you don't set userAddress, it will return all subscribe list.
* @param {string=} userAddress - Address of account you want to get subscribe list.
* @returns Result of transaction.
*/
getSubscribeList(userAddress?: string) {
if (!userAddress) return this.subscribeTable;
return this.subscribeTable[userAddress];
}
/**
* Unsubscribe to specific service reponse.
* @param {string} userAddress - Address of account you want to unsubscribe.
* @param {string} appName - App name you want to unsubscribe.
* @returns True if successfuly unsubscribed.
*/
unsubscribe(userAddress:string, appName: string) {
if (!this.checkSubscribeTableExists(userAddress, appName)) {
throw new Error("Not subscribed");
}
this.ain.em.unsubscribe(
this.subscribeTable[userAddress][appName],
async unsubscribe(filterId: string) {
this.checkEventManager();
await this.em!.unsubscribe(
filterId,
(err)=>{
if (err) {
throw new Error(err.message);
} else {
this.subscribeTable[userAddress][appName] = null;
return true;
}
});
}
Expand Down
46 changes: 0 additions & 46 deletions src/modules/moduleBase.ts

This file was deleted.

0 comments on commit c409c54

Please sign in to comment.