how to halt meteorjs collection subscription

I am facing an issue with stopping a subscription process.

Here is the current code I am using:

if (Meteor.isClient) {

    Meteor.autorun(function(){
        var query;
        query = Session.get('search.query');
        if (!query) return;
        if (Envi.temp.searchSubscribtion) {
            console.log('Subscription for search needs to be stopped ... ');
            Envi.temp.searchSubscribtion.stop();
        }

        Envi.temp.searchSubscribtion = Meteor.subscribe('search', query, {
            onReady : function () {
                console.log('Finished.');
            }
        });
    });

}

'Env' is a global function where subscriptions are temporarily stored in temp.searchSubscribtion.

The issue at hand: when I change the value of search.query to a query that retrieves all items, the "Finished" console log is displayed after about 1 minute.

However, when I change search.query to a query that retrieves only a few items, the "Finished" console log displays after approximately 5 seconds.

It seems there is a difference in processing time between long and short queries.

My goal now is to cancel the currently running subscription when a query is changed, and start a new one. However, when I switch from a long query to a short query immediately, the "Finished" console log still takes more than 1 minute to display.

Even though "

Envi.temp.searchSubscribtion.stop();
" is being executed (as seen in the console log), the subscription does not stop - it appears that the server finishes the first subscription before moving on to the second, as if they are queued.

Do you have any ideas on how to effectively cancel a running subscription?

Answer №1

As the original query is taking a considerable amount of time to return, it causes the single Fiber responsible for running your subscriptions to be stalled. This means that you won't be able to send any other subscription commands (such as stop or new subscription) until the initial query completes.

To address this issue, there are several options available:

  1. Optimize the query for faster execution (consider using indexes).
  2. Publish all documents with limited fields and perform the search on the client side. You can then subscribe to the full set of fields by sending a list of _id's.
  3. Avoid using a publication and instead send data via Meteor.methods (non-reactive/auto-publish).
  4. Combine options 2 and 3; create a meteor method to execute the query and return a list of _id's, then subscribe to that list of _id's.
  5. Implement option 4 but utilize a server-side route to prevent blocking meteor methods when making multiple calls.

When utilizing Meteor.methods, ensure to prevent fiber blocking by following these steps:

  1. When calling from the client, use
    Meteor.apply('myMethod',[parameter1, parameter2 /* etc */], {wait: false}, callback);
    .
  2. In the method on the server side, call this.unblock() within the method body.

An example implementation for option 4 is provided below:

if (Meteor.isServer) {
  Meteor.methods('search', function (query) {
    this.unblock();
    // implement query logic
    return _.pluck(collection.find(query, {_id: true}).fetch(), '_id');
  });

  Meteor.publish('searchResults', function (resultIds) {
    return collection.find({_id: {$in: resultIds}});
  });
}
if (Meteor.isClient) {

  Meteor.autorun(function () {
    var query;
    query = Session.get('search.query');
    if (!query) return;
    Meteor.apply('search', [query], {wait:false}, function (err, resultIds) {
      if (err) {
        console.log('error!', err);
        return;
      }
      var currentSearch = Session.get('search.query');
      if (!EJSON.equals(currentSearch, query)) {
        console.log('Results returned for', query, ' however current search is ', currentSearch);
        return;
      }

      if (Envi.temp.searchSubscribtion) {
        console.log('Subscription for search needs to be stopped... ');
        Envi.temp.searchSubscribtion.stop();

      }
      Envi.temp.searchSubscribtion = Meteor.subscribe('searchResults', resultIds, {
        onReady: function () {
          console.log('Query complete for:', query);
        }
      });
    });
  });

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process for exporting a class and declaring middleware in TypeScript?

After creating the user class where only the get method is defined, I encountered an issue when using it in middleware. There were no errors during the call to the class, but upon running the code, a "server not found" message appeared. Surprisingly, delet ...

"React - encountering issues with state being undefined when passing child state up through parent components

I am currently navigating the world of react and have encountered a hurdle. I find myself facing difficulties in updating the parent component based on changes in the child state. I was able to pass the child state to the parent by linking the child's ...

How to download an Excel file (xlsx) using AngularJS and WebApi

I am currently working on a project that requires me to download a report in xlsx format. Despite successfully generating the report file on the server and receiving it on the client side, I am facing an issue where the file is not opening and is resulting ...

Python selenium obscured input field

I need help filling a masked phone field that looks like this: +7(___)___-__-__ using Python and Selenium. <input type="tel" name="PHONE" id="phone" class="js-phone-masked"> This is my code snippet: driver.find_element_by_id('phone').cli ...

What is the best way to narrow down a selection of elements in d3js?

I am trying to implement a feature where all elements below the one that is being hovered over will translate downwards. Currently, I am able to filter the selection using .filter for elements greater than 10. Is there a way to dynamically use the id of th ...

Error in MongooseJS Route Error: Strange Casting Issue

I'm currently working on the backend and facing an issue with a specific route intended to return an array of IDs from the database for lazy loading purposes. The route is set up as follows: router.get('/list', (req, res) => { Inside ...

Nested pages are causing jQuery plugins to malfunction

I am currently working on a website, but I am facing some issues with the product listing pages and the tips and tricks page. It appears that there is an issue with jMenu and jFlipBook plugins not functioning properly. Since I didn't develop the origi ...

Hide Panels on amcharts

Is there a way to toggle the visibility of panels without having to delete and recreate them each time? I haven't been able to find any examples online. A big thank you to @Robbert for the helpful reply! I found a way to hide a panel using this code ...

Using JQuery to Iterate Through All Form Inputs

I am attempting to retrieve the values of all input fields from a form using JQuery and store them in an array to be sent via AJAX with a GET request. My initial approach did not yield the desired results: function gatherFormData(){ $('#formId i ...

Once map layers have been loaded initially, they will not render again

I'm currently incorporating Mapbox GL into my Vue project using VueMapbox (0.4.1). <template> <MglMap :accessToken="accessToken" :mapStyle.sync="mapStyle" :repaint="true" @load="onMapLoaded ...

Tips for avoiding the freezing of bootstrap-select scroll when a large number of options are present

I have integrated a bootstrap-select with a total of 1000 options. However, I am encountering an issue where when I attempt to scroll down the list of options, it only goes down approximately 60 options and then freezes in that position. Can anyone provi ...

What is the most effective way to monitor the duration of video playback?

Whenever a user watches a video, I aim to initiate 2 AJAX calls. The first call should trigger when the user finishes watching the entire video or if the time played is equal to or greater than the duration of the video (considering users may rewind). time ...

The jQuery .accordion() feature is not functioning properly due to the failure to load jQuery into the HTML document

I have exhaustively researched online and visited numerous resources, including Stack Overflow. Despite making countless adjustments to my code, it still refuses to function properly. The frustration is mounting as I struggle with jQuery - a technology tha ...

Exploring the integration of Stripe Checkout with React and Express.js

Seeking assistance with integrating Stripe Checkout into my React application. I need to create a route in my nodejs/express server that will provide the session id required for setting up Stripe Checkout on the front end. The aim is to redirect users to s ...

Modifying various items depending on the variable's value

I'm attempting to adjust various variables depending on which button the user clicks. For instance, there are three buttons: <button id="button1" onclick="isClicked(this.id)">B1</button> <button id="button2" onclick="isClicked(this.id) ...

Guide on creating a hover-based side menu

I am looking to enhance the sub-menus like PRODUCT 1, PRODUCT 2, etc. by adding side menus that appear when hovering over them. Can anyone assist with implementing this feature in the code below? Below is the current code snippet: CSS: @import url(http: ...

Tips for automatically scrolling up when a button is clicked and an error occurs in a lengthy message

My long scrollable form saves data when the button is clicked, but how can I automatically scroll up if an error occurs? I have created a form with 40 points to list, including dropdowns, textboxes, and checkboxes. There are mandatory fields as well. Howe ...

Submitting an ASP.NET MVC form with jQuery and passing parameters

Having trouble passing the ThreadId parameter when submitting a form to my controller through jQuery Ajax. The code works fine, but for some reason, the ThreadId doesn't get passed using form.serialize(). Any suggestions on how to effectively pass par ...

Flags of Discord.js PermissionsBitField

Where can I find information on the PermissionsBitField.Flags commands? I am specifically looking for the "Guilds and Guilds_messages" flags but have had trouble locating them. Does anyone know why PermissionsBitField.Flags.Guilds and PermissionsBitField. ...

There was an issue with the routing that prevented access to the student activity information at

I've been working on building my own Note Taking App using Express. Following my instructor's example, I wrote some code but encountered an issue when deploying it. Whenever I try to add a new note, I receive an error that says "cannot get/api/na ...