mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
All: Improved request repeating mechanism
This commit is contained in:
parent
69fd32e7c6
commit
3f14878d0f
@ -18,6 +18,10 @@ class FileApiDriverWebDav {
|
|||||||
return this.api_;
|
return this.api_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requestRepeatCount() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
async stat(path) {
|
async stat(path) {
|
||||||
try {
|
try {
|
||||||
const result = await this.api().execPropFind(path, 0, [
|
const result = await this.api().execPropFind(path, 0, [
|
||||||
|
@ -4,6 +4,31 @@ const { shim } = require('lib/shim');
|
|||||||
const BaseItem = require('lib/models/BaseItem.js');
|
const BaseItem = require('lib/models/BaseItem.js');
|
||||||
const JoplinError = require('lib/JoplinError');
|
const JoplinError = require('lib/JoplinError');
|
||||||
const ArrayUtils = require('lib/ArrayUtils');
|
const ArrayUtils = require('lib/ArrayUtils');
|
||||||
|
const { time } = require('lib/time-utils.js');
|
||||||
|
|
||||||
|
function requestCanBeRepeated(error) {
|
||||||
|
const errorCode = typeof error === 'object' && error.code ? error.code : null;
|
||||||
|
|
||||||
|
if (errorCode === 'rejectedByTarget') return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function tryAndRepeat(fn, count) {
|
||||||
|
let retryCount = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
const result = await fn();
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
if (retryCount >= count) throw error;
|
||||||
|
if (!requestCanBeRepeated(error)) throw error;
|
||||||
|
retryCount++;
|
||||||
|
await time.sleep(1 + retryCount * 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class FileApi {
|
class FileApi {
|
||||||
|
|
||||||
@ -16,6 +41,14 @@ class FileApi {
|
|||||||
this.driver_.fileApi_ = this;
|
this.driver_.fileApi_ = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ideally all requests repeating should be done at the FileApi level to remove duplicate code in the drivers, but
|
||||||
|
// historically some drivers (eg. OneDrive) are already handling request repeating, so this is optional, per driver,
|
||||||
|
// and it defaults to no repeating.
|
||||||
|
requestRepeatCount() {
|
||||||
|
if (this.driver_.requestRepeatCount) return this.driver_.requestRepeatCount();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
tempDirName() {
|
tempDirName() {
|
||||||
if (this.tempDirName_ === null) throw Error('Temp dir not set!');
|
if (this.tempDirName_ === null) throw Error('Temp dir not set!');
|
||||||
return this.tempDirName_;
|
return this.tempDirName_;
|
||||||
@ -59,50 +92,70 @@ class FileApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DRIVER MUST RETURN PATHS RELATIVE TO `path`
|
// DRIVER MUST RETURN PATHS RELATIVE TO `path`
|
||||||
list(path = '', options = null) {
|
async list(path = '', options = null) {
|
||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
if (!('includeHidden' in options)) options.includeHidden = false;
|
if (!('includeHidden' in options)) options.includeHidden = false;
|
||||||
if (!('context' in options)) options.context = null;
|
if (!('context' in options)) options.context = null;
|
||||||
|
|
||||||
this.logger().debug('list ' + this.baseDir_);
|
this.logger().debug('list ' + this.baseDir_);
|
||||||
|
|
||||||
return this.driver_.list(this.baseDir_, options).then((result) => {
|
const result = await tryAndRepeat(() => this.driver_.list(this.baseDir_, options), this.requestRepeatCount());
|
||||||
if (!options.includeHidden) {
|
|
||||||
let temp = [];
|
if (!options.includeHidden) {
|
||||||
for (let i = 0; i < result.items.length; i++) {
|
let temp = [];
|
||||||
if (!isHidden(result.items[i].path)) temp.push(result.items[i]);
|
for (let i = 0; i < result.items.length; i++) {
|
||||||
}
|
if (!isHidden(result.items[i].path)) temp.push(result.items[i]);
|
||||||
result.items = temp;
|
|
||||||
}
|
}
|
||||||
return result;
|
result.items = temp;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
// return this.driver_.list(this.baseDir_, options).then((result) => {
|
||||||
|
// if (!options.includeHidden) {
|
||||||
|
// let temp = [];
|
||||||
|
// for (let i = 0; i < result.items.length; i++) {
|
||||||
|
// if (!isHidden(result.items[i].path)) temp.push(result.items[i]);
|
||||||
|
// }
|
||||||
|
// result.items = temp;
|
||||||
|
// }
|
||||||
|
// return result;
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprectated
|
// Deprectated
|
||||||
setTimestamp(path, timestampMs) {
|
setTimestamp(path, timestampMs) {
|
||||||
this.logger().debug('setTimestamp ' + this.fullPath_(path));
|
this.logger().debug('setTimestamp ' + this.fullPath_(path));
|
||||||
return this.driver_.setTimestamp(this.fullPath_(path), timestampMs);
|
return tryAndRepeat(() => this.driver_.setTimestamp(this.fullPath_(path), timestampMs), this.requestRepeatCount());
|
||||||
|
//return this.driver_.setTimestamp(this.fullPath_(path), timestampMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
mkdir(path) {
|
mkdir(path) {
|
||||||
this.logger().debug('mkdir ' + this.fullPath_(path));
|
this.logger().debug('mkdir ' + this.fullPath_(path));
|
||||||
return this.driver_.mkdir(this.fullPath_(path));
|
return tryAndRepeat(() => this.driver_.mkdir(this.fullPath_(path)), this.requestRepeatCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
stat(path) {
|
async stat(path) {
|
||||||
this.logger().debug('stat ' + this.fullPath_(path));
|
this.logger().debug('stat ' + this.fullPath_(path));
|
||||||
return this.driver_.stat(this.fullPath_(path)).then((output) => {
|
|
||||||
if (!output) return output;
|
const output = await tryAndRepeat(() => this.driver_.stat(this.fullPath_(path)), this.requestRepeatCount());
|
||||||
output.path = path;
|
|
||||||
return output;
|
if (!output) return output;
|
||||||
});
|
output.path = path;
|
||||||
|
return output;
|
||||||
|
|
||||||
|
// return this.driver_.stat(this.fullPath_(path)).then((output) => {
|
||||||
|
// if (!output) return output;
|
||||||
|
// output.path = path;
|
||||||
|
// return output;
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
get(path, options = null) {
|
get(path, options = null) {
|
||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
if (!options.encoding) options.encoding = 'utf8';
|
if (!options.encoding) options.encoding = 'utf8';
|
||||||
this.logger().debug('get ' + this.fullPath_(path));
|
this.logger().debug('get ' + this.fullPath_(path));
|
||||||
return this.driver_.get(this.fullPath_(path), options);
|
return tryAndRepeat(() => this.driver_.get(this.fullPath_(path), options), this.requestRepeatCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
async put(path, content, options = null) {
|
async put(path, content, options = null) {
|
||||||
@ -112,32 +165,32 @@ class FileApi {
|
|||||||
if (!await this.fsDriver().exists(options.path)) throw new JoplinError('File not found: ' + options.path, 'fileNotFound');
|
if (!await this.fsDriver().exists(options.path)) throw new JoplinError('File not found: ' + options.path, 'fileNotFound');
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.driver_.put(this.fullPath_(path), content, options);
|
return tryAndRepeat(() => this.driver_.put(this.fullPath_(path), content, options), this.requestRepeatCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(path) {
|
delete(path) {
|
||||||
this.logger().debug('delete ' + this.fullPath_(path));
|
this.logger().debug('delete ' + this.fullPath_(path));
|
||||||
return this.driver_.delete(this.fullPath_(path));
|
return tryAndRepeat(() => this.driver_.delete(this.fullPath_(path)), this.requestRepeatCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprectated
|
// Deprectated
|
||||||
move(oldPath, newPath) {
|
move(oldPath, newPath) {
|
||||||
this.logger().debug('move ' + this.fullPath_(oldPath) + ' => ' + this.fullPath_(newPath));
|
this.logger().debug('move ' + this.fullPath_(oldPath) + ' => ' + this.fullPath_(newPath));
|
||||||
return this.driver_.move(this.fullPath_(oldPath), this.fullPath_(newPath));
|
return tryAndRepeat(() => this.driver_.move(this.fullPath_(oldPath), this.fullPath_(newPath)), this.requestRepeatCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprectated
|
// Deprectated
|
||||||
format() {
|
format() {
|
||||||
return this.driver_.format();
|
return tryAndRepeat(() => this.driver_.format(), this.requestRepeatCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
clearRoot() {
|
clearRoot() {
|
||||||
return this.driver_.clearRoot(this.baseDir_);
|
return tryAndRepeat(() => this.driver_.clearRoot(this.baseDir_), this.requestRepeatCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
delta(path, options = null) {
|
delta(path, options = null) {
|
||||||
this.logger().debug('delta ' + this.fullPath_(path));
|
this.logger().debug('delta ' + this.fullPath_(path));
|
||||||
return this.driver_.delta(this.fullPath_(path), options);
|
return tryAndRepeat(() => this.driver_.delta(this.fullPath_(path), options), this.requestRepeatCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user