Search code examples
javascriptjquerygoogle-chrome-extension

Chrome Alarm events keeps firing every 4 seconds


I am trying to pass a message triggered by an alarm from background.js to loader.js. Here is my code:

manifest.json:

{
"update_url": "https://clients2.google.com/service/update2/crx",

   "manifest_version": 2,
   "name": "DubX",
   "short_name": "DubX",
   "author": "Al3366",
   "description": "Automatically loads DubX on dubtrack.fm",
   "homepage_url": "https://dubx.net/",
   "version": "0",
   "browser_action": {
    "default_icon": "icons/48.png"
   },
   "permissions": ["background","alarms","tabs"],
   "background": {
      "scripts": ["background.js"],
      "persistent": false
    },
   "content_scripts": [{
      "matches": ["*://www.dubtrack.fm/*"],
      "js": ["jquery.js","loader.js"],
      "run_at": "document_end"
   }],

    "icons": { 
        "16": "icons/16.png",
        "19": "icons/19.png",
        "38": "icons/38.png",
        "48": "icons/48.png",
        "128": "icons/128.png" 
    }
}

background.js

chrome.alarms.create('hello',{delayInMinutes: 0.25});
chrome.alarms.onAlarm.addListener(function(alarm) {
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
        var content = {greeting: 'foo'};
        chrome.tabs.sendMessage(tabs[0].id, content);  
    });
});

loader.js:

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        if (request.greeting === 'foo') {
            hello();
        };
    }
);
$('body').prepend('<div class="cake" style=" z-index: 2147483647; color: white; position: fixed; bottom: 54px; left: 27px; background: #222; padding: 13px; -webkit-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.75); -moz-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.75); box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.75); border-radius: 5px;">Waiting for Dubtrack...</div>');
function hello() {
    $.getScript('https://rawgit.com/sinfulBA/DubX-Script/master/beta.js');
    $('.cake').remove();
};

It keeps firing the hello(); function every 4 seconds. I can't find out what I'm doing wrong. Thanks in advance for your reply.


Solution

  • You're using an event page (non-persistent background page), which is unloaded after approximately 5 seconds of inactivity. Then some activity in the browser causes the background page to re-initialize and set a new alarm. So each 5 seconds that new alarm fires the handler that sends a message which makes the content script call hello().

    • Solution 1: check for some condition before invoking chrome.alarms.create.

      For example, if the real objective is to fire an alarm one time after the browser starts use onStartup event and set the alarm time with when key:

        chrome.runtime.onStartup.addListener(function() {
            chrome.alarms.create('hello', {when: Date.now() + 60*1000});
        });
      

      Note that in a published extension the interval between the next alarm and the last fired alarm is at least 1 minute even if you specify a smaller value like 15 seconds (15*1000).

    • Solution 2 (a bad one): make the background page persistent by using "persistent": true. It's bad because a persistent background page hogs the memory. However, as explained in Xan's answer, it's a perfect one in case you actually need to fire the alarm each 15 seconds.