Skip useless tasks in the worker to improve fast scrolling with scanned books (bug 1866296)
When a page rendering is cancelled, a task is sent to the worker but before it's executed the rendering task is: the cancel task is more or less useless in this case. So in using the fact that draining the message queue has a higher priority than draining the event one, it's possible to get all the current tasks, hence it's possible to cancel some tasks which are before a cancel task.
This commit is contained in:
		
							parent
							
								
									76e3e52021
								
							
						
					
					
						commit
						c0ee0ba841
					
				@ -70,6 +70,14 @@ function wrapReason(reason) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MessageHandler {
 | 
					class MessageHandler {
 | 
				
			||||||
 | 
					  #cancelledStreamIds = new Set();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #executorRunning = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #isPostponed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #queue = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(sourceName, targetName, comObj) {
 | 
					  constructor(sourceName, targetName, comObj) {
 | 
				
			||||||
    this.sourceName = sourceName;
 | 
					    this.sourceName = sourceName;
 | 
				
			||||||
    this.targetName = targetName;
 | 
					    this.targetName = targetName;
 | 
				
			||||||
@ -81,15 +89,62 @@ class MessageHandler {
 | 
				
			|||||||
    this.callbackCapabilities = Object.create(null);
 | 
					    this.callbackCapabilities = Object.create(null);
 | 
				
			||||||
    this.actionHandler = Object.create(null);
 | 
					    this.actionHandler = Object.create(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this._onComObjOnMessage = event => {
 | 
					    this._onComObjOnMessage = ({ data }) => {
 | 
				
			||||||
      const data = event.data;
 | 
					      if (data.targetName === this.sourceName) {
 | 
				
			||||||
      if (data.targetName !== this.sourceName) {
 | 
					        // The meesages in the worker queue are processed with a
 | 
				
			||||||
 | 
					        // higher priority than the tasks in the event queue.
 | 
				
			||||||
 | 
					        // So, postponing the task execution, will ensure that the message
 | 
				
			||||||
 | 
					        // queue is drained.
 | 
				
			||||||
 | 
					        // If at some point we've a cancelled task (e.g. GetOperatorList),
 | 
				
			||||||
 | 
					        // we're able to skip the task execution with the same streamId.
 | 
				
			||||||
 | 
					        this.#queue.push(data);
 | 
				
			||||||
 | 
					        this.#isPostponed ||= data.action === "GetOperatorList";
 | 
				
			||||||
 | 
					        if (data.stream === StreamKind.CANCEL) {
 | 
				
			||||||
 | 
					          this.#cancelledStreamIds.add(data.streamId);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!this.#executorRunning) {
 | 
				
			||||||
 | 
					          this.#executorRunning = true;
 | 
				
			||||||
 | 
					          this.#postponeExecution();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    comObj.addEventListener("message", this._onComObjOnMessage);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #postponeExecution() {
 | 
				
			||||||
 | 
					    if (this.#isPostponed) {
 | 
				
			||||||
 | 
					      setTimeout(this.#executor.bind(this), 0);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      this.#executor();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #executor() {
 | 
				
			||||||
 | 
					    if (this.#queue.length === 0) {
 | 
				
			||||||
 | 
					      this.#cancelledStreamIds.clear();
 | 
				
			||||||
 | 
					      this.#executorRunning = false;
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
      if (data.stream) {
 | 
					
 | 
				
			||||||
 | 
					    const data = this.#queue.shift();
 | 
				
			||||||
 | 
					    const { stream, streamId } = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (stream) {
 | 
				
			||||||
 | 
					      if (
 | 
				
			||||||
 | 
					        stream === StreamKind.CANCEL ||
 | 
				
			||||||
 | 
					        !this.#cancelledStreamIds.has(streamId)
 | 
				
			||||||
 | 
					      ) {
 | 
				
			||||||
        this.#processStreamMessage(data);
 | 
					        this.#processStreamMessage(data);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      this.#postponeExecution();
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (streamId && this.#cancelledStreamIds.has(streamId)) {
 | 
				
			||||||
 | 
					      this.#postponeExecution();
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (data.callback) {
 | 
					    if (data.callback) {
 | 
				
			||||||
      const callbackId = data.callbackId;
 | 
					      const callbackId = data.callbackId;
 | 
				
			||||||
      const capability = this.callbackCapabilities[callbackId];
 | 
					      const capability = this.callbackCapabilities[callbackId];
 | 
				
			||||||
@ -105,6 +160,7 @@ class MessageHandler {
 | 
				
			|||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        throw new Error("Unexpected callback case");
 | 
					        throw new Error("Unexpected callback case");
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      this.#postponeExecution();
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const action = this.actionHandler[data.action];
 | 
					    const action = this.actionHandler[data.action];
 | 
				
			||||||
@ -118,8 +174,8 @@ class MessageHandler {
 | 
				
			|||||||
      new Promise(function (resolve) {
 | 
					      new Promise(function (resolve) {
 | 
				
			||||||
        resolve(action(data.data));
 | 
					        resolve(action(data.data));
 | 
				
			||||||
      }).then(
 | 
					      }).then(
 | 
				
			||||||
          function (result) {
 | 
					        result => {
 | 
				
			||||||
            comObj.postMessage({
 | 
					          this.comObj.postMessage({
 | 
				
			||||||
            sourceName: cbSourceName,
 | 
					            sourceName: cbSourceName,
 | 
				
			||||||
            targetName: cbTargetName,
 | 
					            targetName: cbTargetName,
 | 
				
			||||||
            callback: CallbackKind.DATA,
 | 
					            callback: CallbackKind.DATA,
 | 
				
			||||||
@ -127,8 +183,8 @@ class MessageHandler {
 | 
				
			|||||||
            data: result,
 | 
					            data: result,
 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
          function (reason) {
 | 
					        reason => {
 | 
				
			||||||
            comObj.postMessage({
 | 
					          this.comObj.postMessage({
 | 
				
			||||||
            sourceName: cbSourceName,
 | 
					            sourceName: cbSourceName,
 | 
				
			||||||
            targetName: cbTargetName,
 | 
					            targetName: cbTargetName,
 | 
				
			||||||
            callback: CallbackKind.ERROR,
 | 
					            callback: CallbackKind.ERROR,
 | 
				
			||||||
@ -137,15 +193,12 @@ class MessageHandler {
 | 
				
			|||||||
          });
 | 
					          });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
        return;
 | 
					    } else if (data.streamId) {
 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (data.streamId) {
 | 
					 | 
				
			||||||
      this.#createStreamSink(data);
 | 
					      this.#createStreamSink(data);
 | 
				
			||||||
        return;
 | 
					    } else {
 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      action(data.data);
 | 
					      action(data.data);
 | 
				
			||||||
    };
 | 
					    }
 | 
				
			||||||
    comObj.addEventListener("message", this._onComObjOnMessage);
 | 
					    this.#postponeExecution();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  on(actionName, handler) {
 | 
					  on(actionName, handler) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user