Skip to content

Commit

Permalink
Migrate DeferredProcessor to ES6 classes
Browse files Browse the repository at this point in the history
Stop using the old-style Closure Compiler classes and switch to modern
ES6 classes. Code was *not* reformatted, in order to make the diff
readable; later there'll be a separate commit that'll apply clang-tidy.

A brief overview of the changes:
* Instead of declaring the class by marking a function with
  "@constructor", the "class" ES6 keyword is used.
* Instead of using goog.inherits() for declaring the inheritance, the
  "extends" ES6 keyword is used.
* Static properties are first defined as file-global constants and only
  then copied into the class; this allows using them in the class code,
  since the old-style "this.someConstant" access doesn't work anymore.
  (A side note: ES6 class static properties aren't supported by Closure
  Compiler yet.)
* Calls to the parent class' methods are done via super() instead of the
  Closure Compiler's base() method.

This is expected to be a non-functional change. It contributes to the
refactoring effort tracked by #264.
  • Loading branch information
emaxx-google committed Jul 29, 2021
1 parent 36491f4 commit 0404bf2
Showing 1 changed file with 46 additions and 41 deletions.
87 changes: 46 additions & 41 deletions common/js/src/deferred-processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,26 @@ const GSC = GoogleSmartCard;
const suppressUnhandledRejectionError =
GSC.PromiseHelpers.suppressUnhandledRejectionError;

/**
* This structure is used to store the jobs in a queue.
* @struct
*/
class Job {
/**
* @param {function()} jobFunction The job function that needs to be executed.
* @param {!goog.promise.Resolver} promiseResolver The promise (with methods to
* resolve it) which should be used for returning the job result.
*/
constructor(jobFunction, promiseResolver) {
/** @const */
this.jobFunction = jobFunction;
/** @const */
this.promiseResolver = promiseResolver;
}
}

const logger = GSC.Logging.getScopedLogger('DeferredProcessor');

/**
* This class can be used to organize a processing of jobs that is deferred
* until the specified promise is resolved.
Expand All @@ -56,12 +76,14 @@ const suppressUnhandledRejectionError =
*
* Note that the class supports nested use cases: the addJob() method is safe to
* be called from inside another job.
*/
GSC.DeferredProcessor = class extends goog.Disposable {

/**
* @param {!goog.Promise} awaitedPromise
* @constructor
* @extends goog.Disposable
*/
GSC.DeferredProcessor = function(awaitedPromise) {
DeferredProcessor.base(this, 'constructor');
constructor(awaitedPromise) {
super();

/**
* This flag gets true once the awaited promise is resolved, or once the self
Expand All @@ -85,28 +107,6 @@ GSC.DeferredProcessor = function(awaitedPromise) {
awaitedPromise.then(
this.promiseResolvedListener_.bind(this),
this.promiseRejectedListener_.bind(this));
};

const DeferredProcessor = GSC.DeferredProcessor;

goog.inherits(DeferredProcessor, goog.Disposable);

DeferredProcessor.prototype.logger =
GSC.Logging.getScopedLogger('DeferredProcessor');

/**
* This structure is used to store the jobs in a queue.
* @param {function()} jobFunction The job function that needs to be executed.
* @param {!goog.promise.Resolver} promiseResolver The promise (with methods to
* resolve it) which should be used for returning the job result.
* @constructor
* @struct
*/
function Job(jobFunction, promiseResolver) {
/** @const */
this.jobFunction = jobFunction;
/** @const */
this.promiseResolver = promiseResolver;
}

/**
Expand All @@ -121,7 +121,7 @@ function Job(jobFunction, promiseResolver) {
* @param {function()} jobFunction
* @return {!goog.Promise}
*/
DeferredProcessor.prototype.addJob = function(jobFunction) {
addJob(jobFunction) {
// Enqueue the job regardless of the state. This allows to deal nicely with
// the nested cases.
const promiseResolver = goog.Promise.withResolver();
Expand All @@ -130,40 +130,40 @@ DeferredProcessor.prototype.addJob = function(jobFunction) {
if (this.isSettled_)
this.flushEnqueuedJobs_();
return promiseResolver.promise;
};
}

/** @override */
DeferredProcessor.prototype.disposeInternal = function() {
disposeInternal() {
this.isSettled_ = true;
this.flushEnqueuedJobs_();

goog.log.fine(this.logger, 'Disposed');
goog.log.fine(logger, 'Disposed');

DeferredProcessor.base(this, 'disposeInternal');
};
super.disposeInternal();
}

/** @private */
DeferredProcessor.prototype.promiseResolvedListener_ = function() {
promiseResolvedListener_() {
if (this.isDisposed())
return;
if (this.isSettled_)
return;
this.isSettled_ = true;
goog.log.fine(this.logger, 'The awaited promise was resolved');
goog.log.fine(logger, 'The awaited promise was resolved');
this.flushEnqueuedJobs_();
};
}

/** @private */
DeferredProcessor.prototype.promiseRejectedListener_ = function() {
promiseRejectedListener_() {
if (this.isDisposed())
return;
goog.log.fine(this.logger, 'The awaited promise was rejected, disposing...');
goog.log.fine(logger, 'The awaited promise was rejected, disposing...');
this.dispose();
};
}

/** @private */
DeferredProcessor.prototype.flushEnqueuedJobs_ = function() {
GSC.Logging.checkWithLogger(this.logger, this.isSettled_);
flushEnqueuedJobs_() {
GSC.Logging.checkWithLogger(logger, this.isSettled_);

// Use a flag to prevent nested loops of jobs flushing.
if (this.isCurrentlyFlushingJobs_) {
Expand Down Expand Up @@ -194,7 +194,12 @@ DeferredProcessor.prototype.flushEnqueuedJobs_ = function() {
}
}

GSC.Logging.checkWithLogger(this.logger, this.isCurrentlyFlushingJobs_);
GSC.Logging.checkWithLogger(logger, this.isCurrentlyFlushingJobs_);
this.isCurrentlyFlushingJobs_ = false;
}

};

GSC.DeferredProcessor.logger = logger;

}); // goog.scope

0 comments on commit 0404bf2

Please sign in to comment.