Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic Storage Location Autoleveling #136

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/inode.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ var Inode = {
// generate a hash of the block to use as a handle/filename
block_object.block_hash = utils.sha1_to_hex(block);

utils.commit_block_to_disk(block, block_object, next_storage_location, function(err, result){
var retries = config.STORAGE_LOCATIONS.length;
utils.commit_block_to_disk(block, block_object, next_storage_location, retries, function(err, result){
if (err) {
return callback(err);
}
Expand Down
45 changes: 34 additions & 11 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,32 +91,59 @@ module.exports.load_inode = function load_inode(uri, callback){
};

module.exports.commit_block_to_disk = function commit_block_to_disk(block, block_object, next_storage_location, callback) {

// if storage locations exist, save the block to disk
var total_locations = config.STORAGE_LOCATIONS.length;

if(total_locations > 0){

// check all storage locations to see if we already have this block

var on_complete = function on_complete(found_block){
// TODO: consider increasing found count to enable block redundancy
if(!found_block){

// write new block to next storage location
// TODO: consider implementing in-band compression here
// Keep track of how many storage locations we try when writes fail
var block_write_retries_remaining = config.STORAGE_LOCATIONS.length;
var dir = config.STORAGE_LOCATIONS[next_storage_location].path;
operations.write(dir + block_object.block_hash, block, "binary", function(err){

// TODO: Figure out why dir goes out of scope so we don't have to do this dumb reassignment
var dir = config.STORAGE_LOCATIONS[next_storage_location].path;
if (err) {
return callback(err);
}

// If we can't write the block, try other locations
var current_storage_dir = dir;

// Give-up if we've tried all the storage locations
// NOTE: I don't think this will ever get tripped,
// because the request will fail if the inode cannot
// get written anywhere and that check kicks-in first
block_write_retries_remaining--;
if(block_write_retries_remaining < 0){
log.message(log.ERROR, "Unable to write block to any storage locations!");
return callback(err);
}

// increment (or reset) storage location (striping)
next_storage_location++;
if(next_storage_location === config.STORAGE_LOCATIONS.length){
next_storage_location = 0;
}

var dir = config.STORAGE_LOCATIONS[next_storage_location].path;
log.message(log.INFO, "Error writing block to " + current_storage_dir +", trying " + dir);

operations.write(dir + block_object.block_hash, block, "binary", function(err){
if(err){
return callback(err);
}
});
}
block_object.last_seen = dir;
log.message(log.INFO, "New block " + block_object.block_hash + " written to " + dir);

return callback(null, block_object);

});

} else {
log.message(log.INFO, "Duplicate block " + block_object.block_hash + " not written to disk");
return callback(null, block_object);
Expand All @@ -127,20 +154,16 @@ module.exports.commit_block_to_disk = function commit_block_to_disk(block, block
var location = config.STORAGE_LOCATIONS[idx];
var file = location.path + block_object.block_hash;
idx++;

operations.exists(file + ".gz", function(err, result){

if (result) {
log.message(log.INFO, "Duplicate compressed block " + block_object.block_hash + " found in " + location.path);
block_object.last_seen = location.path;
return on_complete(true);
} else {
operations.exists(file, function(err_2, result_2){

if (err_2) {
log.message(log.INFO, "Block " + block_object.block_hash + " not found in " + location.path);
}

if (result_2) {
log.message(log.INFO, "Duplicate block " + block_object.block_hash + " found in " + location.path);
block_object.last_seen = location.path;
Expand Down