2018-02-06 22:31:18 +00:00
|
|
|
const config = require('../config');
|
|
|
|
const Metadata = require('../metadata');
|
|
|
|
const mozlog = require('../log');
|
|
|
|
const createRedisClient = require('./redis');
|
|
|
|
|
|
|
|
class DB {
|
|
|
|
constructor(config) {
|
2018-08-08 18:07:09 +00:00
|
|
|
const Storage =
|
|
|
|
config.s3_buckets.length > 0 ? require('./s3') : require('./fs');
|
2018-02-06 22:31:18 +00:00
|
|
|
this.log = mozlog('send.storage');
|
2018-08-08 18:07:09 +00:00
|
|
|
|
|
|
|
this.storage = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < config.num_of_buckets; i++) {
|
|
|
|
this.storage.push(new Storage(config, i, this.log));
|
|
|
|
}
|
|
|
|
|
2018-02-06 22:31:18 +00:00
|
|
|
this.redis = createRedisClient(config);
|
|
|
|
this.redis.on('error', err => {
|
|
|
|
this.log.error('Redis:', err);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
async ttl(id) {
|
|
|
|
const result = await this.redis.ttlAsync(id);
|
|
|
|
return Math.ceil(result) * 1000;
|
|
|
|
}
|
|
|
|
|
2018-08-08 18:07:09 +00:00
|
|
|
async getBucket(id) {
|
|
|
|
return this.redis.hgetAsync(id, 'bucket');
|
2018-02-06 22:31:18 +00:00
|
|
|
}
|
|
|
|
|
2018-08-08 18:07:09 +00:00
|
|
|
async length(id) {
|
|
|
|
const bucket = await this.redis.hgetAsync(id, 'bucket');
|
|
|
|
return this.storage[bucket].length(id);
|
2018-02-06 22:31:18 +00:00
|
|
|
}
|
|
|
|
|
2018-08-08 18:07:09 +00:00
|
|
|
async get(id) {
|
|
|
|
const bucket = await this.redis.hgetAsync(id, 'bucket');
|
|
|
|
return this.storage[bucket].getStream(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
async set(id, file, meta, expireSeconds = config.default_expire_seconds) {
|
|
|
|
const bucketTimes = config.expire_times_seconds;
|
|
|
|
let bucket = 0;
|
|
|
|
while (bucket < config.num_of_buckets - 1) {
|
|
|
|
if (expireSeconds <= bucketTimes[bucket]) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bucket++;
|
|
|
|
}
|
|
|
|
|
|
|
|
await this.storage[bucket].set(id, file);
|
|
|
|
this.redis.hset(id, 'bucket', bucket);
|
2018-02-06 22:31:18 +00:00
|
|
|
this.redis.hmset(id, meta);
|
2018-08-08 18:07:09 +00:00
|
|
|
this.redis.expire(id, expireSeconds);
|
2018-02-06 22:31:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
setField(id, key, value) {
|
|
|
|
this.redis.hset(id, key, value);
|
|
|
|
}
|
|
|
|
|
2018-08-08 18:07:09 +00:00
|
|
|
async del(id) {
|
|
|
|
const bucket = await this.redis.hgetAsync(id, 'bucket');
|
2018-02-06 22:31:18 +00:00
|
|
|
this.redis.del(id);
|
2018-08-08 18:07:09 +00:00
|
|
|
this.storage[bucket].del(id);
|
2018-02-06 22:31:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async ping() {
|
|
|
|
await this.redis.pingAsync();
|
2018-08-08 18:07:09 +00:00
|
|
|
for (const bucket of this.storage) {
|
|
|
|
bucket.ping();
|
|
|
|
}
|
2018-02-06 22:31:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async metadata(id) {
|
|
|
|
const result = await this.redis.hgetallAsync(id);
|
|
|
|
return result && new Metadata(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = new DB(config);
|