pixl-server-storage 3.0.16 → 3.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -315,6 +315,58 @@ module.exports = Class.create({
315
315
  inp.pipe( outp );
316
316
  },
317
317
 
318
+ putStreamCustom: function(key, inp, opts, callback) {
319
+ // store key+stream of data to disk
320
+ var self = this;
321
+ var file = this.getFilePath(key);
322
+
323
+ this.logDebug(9, "Storing Binary Stream Object: " + key, file);
324
+
325
+ var dir = path.dirname( file );
326
+
327
+ var temp_file = this.tempDir + '/' + path.basename(file) + '.tmp.' + this.tempFileCounter;
328
+ this.tempFileCounter = (this.tempFileCounter + 1) % 10000000;
329
+
330
+ // create the write stream to temp file
331
+ var outp = fs.createWriteStream( temp_file, opts || {} );
332
+
333
+ outp.on('error', function(err) {
334
+ // failed to write file
335
+ var msg = "Failed to write file: " + key + ": " + temp_file + ": " + err.message;
336
+ self.logError('file', msg);
337
+ return callback( new Error(msg), null );
338
+ } );
339
+
340
+ outp.on('finish', function() {
341
+ // make sure parent dirs exist, async
342
+ self._makeDirs( dir, 0o0775, function(err) {
343
+ if (err) {
344
+ // failed to create directory
345
+ var msg = "Failed to create directory: " + key + ": " + dir + ": " + err.message;
346
+ self.logError('file', msg);
347
+ return callback( new Error(msg), null );
348
+ }
349
+
350
+ // rename temp file to final
351
+ self._renameFile( temp_file, file, function (err) {
352
+ if (err) {
353
+ // failed to write file
354
+ var msg = "Failed to rename file: " + key + ": " + temp_file + ": " + err.message;
355
+ self.logError('file', msg);
356
+ return callback( new Error(msg), null );
357
+ }
358
+
359
+ // all done
360
+ self.logDebug(9, "Store operation complete: " + key);
361
+ callback(null, null);
362
+ } ); // rename
363
+ } ); // mkdirp
364
+ } ); // pipe finish
365
+
366
+ // pipe inp to outp
367
+ inp.pipe( outp );
368
+ },
369
+
318
370
  head: function(key, callback) {
319
371
  // head value given key
320
372
  var self = this;
package/engines/S3.js CHANGED
@@ -166,6 +166,33 @@ module.exports = Class.create({
166
166
  } );
167
167
  },
168
168
 
169
+ putStreamCustom: function(key, inp, opts, callback) {
170
+ // store key+stream of data to S3, inc options
171
+ var self = this;
172
+ var orig_key = key;
173
+ key = this.prepKey(key);
174
+
175
+ var params = {};
176
+ params.Key = this.extKey(key, orig_key);
177
+ params.Body = inp;
178
+ if (opts) Tools.mergeHashInto(params, opts);
179
+
180
+ this.logDebug(9, "Storing S3 Binary Stream: " + key);
181
+
182
+ // double-callback protection (bug in aws-sdk)
183
+ var done = false;
184
+ this.s3.upload(params, function(err, data) {
185
+ if (done) return; else done = true;
186
+
187
+ if (err) {
188
+ self.logError('s3', "Failed to store stream: " + key + ": " + (err.message || err), err);
189
+ }
190
+ else self.logDebug(9, "Stream store complete: " + key);
191
+
192
+ if (callback) callback(err, data);
193
+ } );
194
+ },
195
+
169
196
  head: function(key, callback) {
170
197
  // head s3 value given key
171
198
  var self = this;
@@ -193,7 +220,14 @@ module.exports = Class.create({
193
220
  if (done) return; else done = true;
194
221
 
195
222
  if (err) {
196
- if ((err.code != 'NoSuchKey') && (err.code != 'NotFound')) {
223
+ if ((err.code == 'NoSuchKey') || (err.code == 'NotFound')) {
224
+ // key not found, special case, don't log an error
225
+ // always include "Not found" in error message
226
+ err = new Error("Failed to head key: " + key + ": Not found");
227
+ err.code = "NoSuchKey";
228
+ }
229
+ else {
230
+ // some other error
197
231
  self.logError('s3', "Failed to head key: " + key + ": " + (err.message || err), err);
198
232
  }
199
233
  callback( err, null );
@@ -277,7 +311,10 @@ module.exports = Class.create({
277
311
  self.logDebug(9, "JSON fetch complete: " + key, self.debugLevel(10) ? body : null);
278
312
  }
279
313
 
280
- callback( null, body );
314
+ callback( null, body, {
315
+ mod: Math.floor((new Date(data.LastModified)).getTime() / 1000),
316
+ len: data.ContentLength
317
+ } );
281
318
  } );
282
319
  },
283
320
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixl-server-storage",
3
- "version": "3.0.16",
3
+ "version": "3.0.19",
4
4
  "description": "A key/value/list storage component for the pixl-server framework.",
5
5
  "author": "Joseph Huckaby <jhuckaby@gmail.com>",
6
6
  "homepage": "https://github.com/jhuckaby/pixl-server-storage",
package/storage.js CHANGED
@@ -226,6 +226,36 @@ module.exports = Class.create({
226
226
  } );
227
227
  },
228
228
 
229
+ putStreamCustom: function(key, stream, opts, callback) {
230
+ // store key+stream with engine-specific opts
231
+ var self = this;
232
+
233
+ if (!this.started) return callback( new Error("Storage has not completed startup.") );
234
+ key = this.normalizeKey( key );
235
+
236
+ if (!this.isBinaryKey(key)) {
237
+ return callback( new Error("Stream values are only allowed with keys containing file extensions, e.g. " + key + ".bin") );
238
+ }
239
+
240
+ // sanity checks
241
+ if (!stream || !stream.pipe) return callback( new Error("Not a valid stream.") );
242
+
243
+ // invoke engine and track perf
244
+ var pf = this.perf.begin('put');
245
+
246
+ this.engine.putStreamCustom( key, stream, opts, function(err) {
247
+ // put complete
248
+ var elapsed = pf.end();
249
+
250
+ if (!err) self.logTransaction('put', key, {
251
+ elapsed_ms: elapsed
252
+ });
253
+
254
+ callback(err);
255
+ if (!err) self.emit('putStream', key);
256
+ } );
257
+ },
258
+
229
259
  putMulti: function(records, callback) {
230
260
  // put multiple records at once, given object of keys and values
231
261
  var self = this;
@@ -324,7 +354,7 @@ module.exports = Class.create({
324
354
  // invoke engine and track perf
325
355
  var pf = this.perf.begin('get');
326
356
 
327
- this.engine.get( key, function(err, value) {
357
+ this.engine.get( key, function(err, value, info) {
328
358
  // get complete
329
359
  var elapsed = pf.end();
330
360
 
@@ -339,8 +369,8 @@ module.exports = Class.create({
339
369
  elapsed_ms: elapsed
340
370
  });
341
371
 
342
- callback(null, value);
343
- if (!err) self.emit('get', key, value);
372
+ callback(null, value, info);
373
+ if (!err) self.emit('get', key, value, info);
344
374
  } );
345
375
  },
346
376