hunk.code_window:                                 baseUrl + "/api/v1/releases?instanceId=" + instanceId +
                                           // isCloudHosted should be true only for our cloud instance,
                                           // For docker images that burn the segment key with the image, the CE key will be present
                                           "&isSourceInstall=" + (commonConfig.isCloudHosted() || StringUtils.isEmpty(segmentConfig.getCeKey())) +
                                           (StringUtils.isEmpty(commonConfig.getRepo()) ? "" : ("&repo=" + commonConfig.getRepo()))
                           )
                           .get()
                           .exchange()
                   )
  
hunk.labels: keep keep keep replace keep keep keep keep keep
hunk.after_edit:                                         "&isSourceInstall=" + (commonConfig.isCloudHosting() || StringUtils.isEmpty(segmentConfig.getCeKey())) +
  
hunk.file_path: app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ReleaseNotesService.java
hunk.type: replace
file: import { GracefulWorkerService } from "./WorkerUtil";
  import { runSaga } from "redux-saga";
  import WebpackWorker from "worker-loader!";
  
  const MessageType = "message";
  class MockWorker implements WebpackWorker {
    // Implement interface
    onmessage: any;
    onmessageerror: any;
    dispatchEvent: any;
    onerror: any;
  
    callback: CallableFunction;
    noop: CallableFunction;
    messages: Array<any>;
    delayMilliSeconds: number;
    static instance: MockWorker | undefined;
    responses: Set<number>;
    running: boolean;
  
    static resetInstance() {
      MockWorker.instance = undefined;
    }
  
    constructor() {
      /* eslint-disable @typescript-eslint/no-empty-function */
      this.noop = () => {};
      this.callback = this.noop;
      this.messages = [];
      this.delayMilliSeconds = 0;
      this.responses = new Set<number>();
      MockWorker.instance = this;
      this.running = true;
    }
  
    addEventListener(msgType: string, callback: any) {
      expect(msgType).toEqual(MessageType);
      this.callback = callback;
    }
  
    removeEventListener(msgType: string, callback: any) {
      expect(msgType).toEqual(MessageType);
      expect(callback).toEqual(this.callback);
      this.callback = this.noop;
    }
  
    postMessage(message: any) {
      expect(this.running).toEqual(true);
      expect(this.callback).not.toEqual(this.noop);
      this.messages.push(message);
      const counter = setTimeout(() => {
        const response = {
          requestId: message.requestId,
          responseData: message.requestData,
        };
        this.sendEvent({ data: response });
        this.responses.delete(counter);
      }, this.delayMilliSeconds);
      this.responses.add(counter);
    }
  
    sendEvent(ev: any) {
      expect(this.running).toEqual(true);
      expect(this.callback).not.toEqual(this.noop);
      this.callback(ev);
    }
  
    terminate() {
      this.running = false;
      expect(this.callback).toEqual(this.noop);
      this.responses.forEach((counter) => {
        clearTimeout(counter);
      });
      this.responses = new Set<number>();
    }
  }
  
  describe("GracefulWorkerService", () => {
    beforeEach(() => {
      MockWorker.resetInstance();
      // Assert we don't have an instance from before
      expect(MockWorker.instance).toBeUndefined();
    });
  
    test("Worker should start", async () => {
      const w = new GracefulWorkerService(MockWorker);
  
      // wait for worker to start
      await runSaga({}, w.start);
      if (MockWorker.instance === undefined) {
        expect(MockWorker.instance).toBeDefined();
        return;
      }
      expect(MockWorker.instance.callback).not.toEqual(MockWorker.instance.noop);
    });
  
    test("Independent requests should respond independently irrespective of order", async () => {
      const w = new GracefulWorkerService(MockWorker);
      await runSaga({}, w.start);
      const message1 = { tree: "hello" };
      const message2 = { tree: "world" };
      // Send requests in order
      const result1 = await runSaga({}, w.request, "test", message1);
      const result2 = await runSaga({}, w.request, "test", message2);
      // wait for responses out of order
      const resp2 = await result2.toPromise();
      const resp1 = await result1.toPromise();
      expect(resp1).toEqual(message1);
      expect(resp2).toEqual(message2);
    });
  
    test("Request should wait for ready", async () => {
      const w = new GracefulWorkerService(MockWorker);
      const message = { hello: "world" };
      // Send a request before starting
      const result = await runSaga({}, w.request, "test", message);
      // trigger start after the worker is already waiting
      runSaga({}, w.start);
      const resp = await result.toPromise();
      expect(resp).toEqual(message);
    });
  
    test("Worker should wait to drain in-flight requests before shutdown", async () => {
      const w = new GracefulWorkerService(MockWorker);
      const message = { hello: "world" };
      await runSaga({}, w.start);
      const start = performance.now();
      // Need this to work with eslint
      if (MockWorker.instance === undefined) {
        expect(MockWorker.instance).toBeDefined();
        return;
      }
      // Typical run takes less than 10ms
      // we add a delay of 100ms to check if shutdown waited for pending requests.
      MockWorker.instance.delayMilliSeconds = 100;
  
      const result = await runSaga({}, w.request, "test", message);
      // wait for shutdown
      await (await runSaga({}, w.shutdown)).toPromise();
      // Shutdown shouldn't happen till we get a response
      expect(performance.now() - start).toBeGreaterThanOrEqual(
        MockWorker.instance.delayMilliSeconds,
      );
      const resp = await result.toPromise();
      expect(resp).toEqual(message);
    });
  
    test("Worker restart should work", async () => {
      const w = new GracefulWorkerService(MockWorker);
      const message1 = { tree: "hello" };
      await runSaga({}, w.start);
  
      // Need this to work with eslint
      if (MockWorker.instance === undefined) {
        expect(MockWorker.instance).toBeDefined();
        return;
      }
      // Keep a reference to the old instance to check later
      const oldInstance = MockWorker.instance;
      const result1 = await runSaga({}, w.request, "test", message1);
      expect(await result1.toPromise()).toEqual(message1);
      // stop the worker
      await (await runSaga({}, w.shutdown)).toPromise();
      // Should have called terminate on worker
      expect(oldInstance.running).toEqual(false);
  
      // Send a message to the new worker before starting it
      const message2 = { tree: "world" };
      const result2 = await runSaga({}, w.request, "test", message2);
  
      await runSaga({}, w.start);
  
      // We should have a new instance of the worker
      expect(MockWorker.instance).not.toEqual(oldInstance);
      // The new worker should get the correct message
      expect(await result2.toPromise()).toEqual(message2);
    });
  
    test("Cancelling saga before starting up should not crash", async () => {
      const w = new GracefulWorkerService(MockWorker);
      const message = { tree: "hello" };
  
      const task = await runSaga({}, w.request, "cancel_test", message);
      // Start shutting down
      const shutdown = await runSaga({}, w.shutdown);
      task.cancel();
      // wait for shutdown
      await shutdown.toPromise();
      expect(await task.toPromise()).not.toEqual(message);
    });
  
    test("Cancelled saga should clean up", async () => {
      const w = new GracefulWorkerService(MockWorker);
      const message = { tree: "hello" };
      await runSaga({}, w.start);
  
      // Need this to work with eslint
      if (MockWorker.instance === undefined) {
        expect(MockWorker.instance).toBeDefined();
        return;
      }
      // Make sure we get a chance to cancel before the worker can respond
      MockWorker.instance.delayMilliSeconds = 100;
      const task = await runSaga({}, w.request, "cancel_test", message);
      // Start shutting down
      const shutdown = await runSaga({}, w.shutdown);
      task.cancel();
      // wait for shutdown
      await shutdown.toPromise();
      expect(await task.toPromise()).not.toEqual(message);
    });
  });
  