DTP Social Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

103 lines
2.7 KiB

// host-cache.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0
'use strict';
const dgram = require('dgram');
const uuidv4 = require('uuid').v4;
const { SiteService, SiteError } = require('../../lib/site-lib');
class HostCacheService extends SiteService {
constructor (dtp) {
super(dtp, module.exports);
this.transactions = { };
}
async start ( ) {
await super.start();
this.log.info('creating UDP host-cache socket');
this.hostCache = dgram.createSocket('udp4', this.onMessage.bind(this));
this.hostCache.on('error', this.onError.bind(this));
this.log.info('connecting UDP host-cache socket');
this.hostCache.bind(0, '127.0.0.1');
const HOST_PORT = parseInt(process.env.DTP_HOST_CACHE_PORT || '8000', 10);
this.hostCache.connect(HOST_PORT, '127.0.0.1');
}
async stop ( ) {
if (this.hostCache) {
this.log.info('disconnecting UDP host-cache socket');
this.hostCache.disconnect();
delete this.hostCache;
}
await super.stop();
}
async getFile (bucket, key) {
return new Promise((resolve, reject) => {
const transaction = { tid: uuidv4(), bucket, key, resolve, reject };
this.transactions[transaction.tid] = transaction;
const message = JSON.stringify({
tid: transaction.tid,
cmd: 'getFile',
params: { bucket, key },
});
this.hostCache.send(message);
});
}
async onMessage (message, rinfo) {
message = message.toString('utf8');
message = JSON.parse(message);
switch (message.res.cmd) {
case 'getFile':
return this.onGetFile(message, rinfo);
}
}
async onGetFile (message) {
const transaction = this.transactions[message.tid];
if (!transaction) {
this.log.error('getFile response received with no matching transaction', { tid: message.tid });
return;
}
if (!message.res.success) {
transaction.reject(new SiteError(message.res.statusCode, message.res.message));
delete this.transactions[message.tid];
return;
}
transaction.resolve({
success: message.res.success,
message: message.res.message,
file: message.res.file,
flags: message.flags,
duration: message.duration,
});
delete this.transactions[message.tid];
}
async onError (error) {
this.log.error('onError', { error });
if ((error.errno !== -111) || (error.code !== 'ECONNREFUSED')) {
return;
}
const keys = Object.keys(this.transactions);
keys.forEach((key) => {
const transaction = this.transactions[key];
transaction.reject(error);
delete this.transactions[key];
});
}
}
module.exports = {
slug: 'host-cache',
name: 'hostCache',
create: (dtp) => { return new HostCacheService(dtp); },
};