Merge pull request #61 from seguler/retry
Increasing retry count and adding jitter for resiliency
This commit is contained in:
Коммит
18c7f97a24
11
README.md
11
README.md
|
@ -38,7 +38,7 @@ Please take careful note of the following points, before using blobfuse:
|
|||
|
||||
## Installation
|
||||
|
||||
You can install blobfuse from the Linux Software Repository for Microsoft products. The process is explained in the [blobfuse installation](https://github.com/Azure/azure-storage-fuse/wiki/Installation) page. Alternatively, you can clone this repository, install the dependencies (libfuse, libcurl and GnuTLS) and build from source code.
|
||||
You can install blobfuse from the Linux Software Repository for Microsoft products. The process is explained in the [blobfuse installation](https://github.com/Azure/azure-storage-fuse/wiki/Installation) page. Alternatively, you can clone this repository, install the dependencies (libfuse, libcurl and GnuTLS) and build from source code. See details in the [wiki](https://github.com/Azure/azure-storage-fuse/wiki/Installation#build-from-source).
|
||||
|
||||
## Usage
|
||||
|
||||
|
@ -52,6 +52,8 @@ accountKey <account-key-here>
|
|||
containerName <container-name-here>
|
||||
```
|
||||
|
||||
Alternatively provide the account name and key in the environment variables AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_ACCESS_KEY, and set --container-name while mounting.
|
||||
|
||||
By default, blobfuse will use the ephemeral disks in Azure VMs as the local cache (/mnt/blobfusetmp). Please make sure that your user has write access to this location. If not, create and `chown` to your user.
|
||||
|
||||
```
|
||||
|
@ -67,10 +69,11 @@ Now you can mount using the provided mount script (mount.sh):
|
|||
### Mount Options
|
||||
- You can modify the default FUSE options in mount.sh file. All options for FUSE is described in the [FUSE man page](http://manpages.ubuntu.com/manpages/xenial/man8/mount.fuse.8.html)
|
||||
- In addition to the FUSE kernel module options; blobfuse offers following options:
|
||||
* --tmp-path=/path/to/cache : Configures the tmp location for the cache. Always configure the fastest disk (SSD or ramdisk) for best performance.
|
||||
* --config-path=/path/to/connection.cfg : Configures the path for the file where the account credentials are provided
|
||||
* --tmp-path=/path/to/cache : Configures the tmp location for the cache. Always configure the fastest disk (SSD) for best performance.
|
||||
* --use-https=true/false : Enables HTTPS communication with Blob storage. False by defaul. Enable it to protect against data corruption over the wire.
|
||||
* --file-cache-timeout-in-seconds=120 : Blobs will be cached in the temp folder for this many seconds. 120 seconds by default. During this time, blobfuse will not check whether the file is up to date or not.
|
||||
* [OPTIONAL] --container-name=container : Required if no configuration file is specified. Also set account name and key via the environment variables AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_ACCESS_KEY
|
||||
* [OPTIONAL] --use-https=true/false : Enables HTTPS communication with Blob storage. True by default.
|
||||
* [OPTIONAL] --file-cache-timeout-in-seconds=120 : Blobs will be cached in the temp folder for this many seconds. 120 seconds by default. During this time, blobfuse will not check whether the file is up to date or not.
|
||||
|
||||
|
||||
### Notes
|
||||
|
|
|
@ -67,8 +67,8 @@ namespace microsoft_azure {
|
|||
retry_info evaluate(const retry_context &context) const override {
|
||||
if (context.numbers() == 0) {
|
||||
return retry_info(true, std::chrono::seconds(0));
|
||||
} else if (context.numbers() < 3 && can_retry(context.result())) {
|
||||
return retry_info(true, std::chrono::seconds(5));
|
||||
} else if (context.numbers() < 100 && can_retry(context.result())) {
|
||||
return retry_info(true, std::chrono::seconds(5+rand()%5));
|
||||
}
|
||||
return retry_info(false, std::chrono::seconds(0));
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ struct options
|
|||
const char *config_file; // Connection to Azure Storage information (account name, account key, etc)
|
||||
const char *use_https; // True if https should be used (defaults to false)
|
||||
const char *file_cache_timeout_in_seconds; // Timeout for the file cache (defaults to 120 seconds)
|
||||
const char *container_name; //container to mount. Used only if config_file is not provided
|
||||
};
|
||||
|
||||
struct options options;
|
||||
|
@ -33,6 +34,7 @@ const struct fuse_opt option_spec[] =
|
|||
OPTION("--config-file=%s", config_file),
|
||||
OPTION("--use-https=%s", use_https),
|
||||
OPTION("--file-cache-timeout-in-seconds=%s", file_cache_timeout_in_seconds),
|
||||
OPTION("--container-name=%s", container_name),
|
||||
FUSE_OPT_END
|
||||
};
|
||||
|
||||
|
@ -56,6 +58,35 @@ inline bool is_lowercase_string(const std::string &s)
|
|||
})));
|
||||
}
|
||||
|
||||
// Read Storage connection information from the environment variables
|
||||
int read_config_env()
|
||||
{
|
||||
char* env_account = getenv("AZURE_STORAGE_ACCOUNT");
|
||||
char* env_account_key = getenv("AZURE_STORAGE_ACCESS_KEY");
|
||||
|
||||
if(env_account!=NULL)
|
||||
{
|
||||
str_options.accountName = env_account;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "AZURE_STORAGE_ACCOUNT environment variable is empty.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(env_account_key!=NULL)
|
||||
{
|
||||
str_options.accountKey = env_account_key;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "AZURE_STORAGE_ACCESS_KEY environment variable is empty.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read Storage connection information from the config file
|
||||
int read_config(std::string configFile)
|
||||
{
|
||||
|
@ -112,17 +143,17 @@ int read_config(std::string configFile)
|
|||
|
||||
if(str_options.accountName.size() == 0)
|
||||
{
|
||||
fprintf(stderr, "Account name is missing in the configure file.");
|
||||
fprintf(stderr, "Account name is missing in the configure file.\n");
|
||||
return -1;
|
||||
}
|
||||
else if(str_options.accountKey.size() == 0)
|
||||
{
|
||||
fprintf(stderr, "Account key is missing in the configure file.");
|
||||
fprintf(stderr, "Account key is missing in the configure file.\n");
|
||||
return -1;
|
||||
}
|
||||
else if(str_options.containerName.size() == 0)
|
||||
{
|
||||
fprintf(stderr, "Container name is missing in the configure file.");
|
||||
fprintf(stderr, "Container name is missing in the configure file.\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
|
@ -161,8 +192,11 @@ void *azs_init(struct fuse_conn_info * conn)
|
|||
// TODO: print FUSE usage as well
|
||||
void print_usage()
|
||||
{
|
||||
fprintf(stdout, "Usage: blobfuse <mount-folder> --config-file=<config-file> --tmp-path=<temp-path> [--use-https=true] [--file-cache-timeout-in-seconds=120]\n");
|
||||
fprintf(stdout, "Please see https://github.com/Azure/azure-storage-fuse for installation and configuration instructions.\n");
|
||||
fprintf(stdout, "Usage: blobfuse <mount-folder> --tmp-path=</path/to/fusecache> [--config-file=</path/to/config.cfg> | --container-name=<containername>] [--use-https=true] [--file-cache-timeout-in-seconds=120]\n\n");
|
||||
fprintf(stdout, "In addition to setting --tmp-path parameter, you must also do one of the following:\n");
|
||||
fprintf(stdout, "1. Specify a config file (using --config-file]=) with account name, account key, and container name, OR\n");
|
||||
fprintf(stdout, "2. Set the environment variables AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_ACCESS_KEY, and specify the container name with --container-name=\n\n");
|
||||
fprintf(stdout, "See https://github.com/Azure/azure-storage-fuse for detailed installation and configuration instructions.\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -208,7 +242,24 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
ret = read_config(options.config_file);
|
||||
if(!options.config_file)
|
||||
{
|
||||
if(!options.container_name)
|
||||
{
|
||||
fprintf(stderr, "Error: --container-name is not set.\n");
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string container(options.container_name);
|
||||
str_options.containerName = container;
|
||||
ret = read_config_env();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = read_config(options.config_file);
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
return ret;
|
||||
|
|
Загрузка…
Ссылка в новой задаче