Display a Chrome desktop notification every day at specific time - google-chrome-extension

I'd like to write an extension that displays a desktop notification every day at a specified time. Having a quick look through the Chrome APIs, it seems like the only way to do this would be to:
create a background page for my extension,
use setInterval() with a sufficiently low resolution to not tax the CPU (even 5 min is fine),
when interval fires, check if the current time is after the desired time,
ensure that the user has not already been displayed the notification today.
(The details of the last step are irrelevant to my question, just put in to show I realize I need to prevent "flapping" of the notice).
This seems rather indirect and potentially expensive though; is there any way around this? Is the background page needed?
I suppose I could just call setTimeout() and only fire the event once (by calculating how long between now & desired time), then call it again after the notification is shown. For some reason that sounds more "brittle", though I'm not sure why...

I think you will want the background page to do this smoothly. You can't use a content script because you need to keep the "state"/timer.
So when background page first loads (browser start) you work out the current time and the offset to the next notification time and setInterval to that exact interval. That way you won't need to poll every five minutes and/or work out if you've shown the message. You simply show it at the exact time required. This has to be far more efficient, effective and cleaner than polling. At notification you just reset the interval again.
Some sample functions here:
setTimeout but for a given time
From reading the above post and from a quick search on the net it appears that you should have no problem calling setInterval for an interval such as once a day. Calvin suggests 25 days!
That is how I would approach it.
EDIT: Since posting one thing that has sprung to mind is what happens if a PC gets hibernated for n hours? I need to test this myself for a similar project so I will update once I've had a chance to test this out.

Related

Chrome Extension performance difference - alarm + history vs storage + history

My extension(manifest v3) needs to track the number of times a set of websites are visited either during the whole day or during certain time windows and then perform an action if the visit count exceeds a limit.
There are two ways I could think of implementing this:
alarm + history: Create an alarm that runs every 5 mins, search the history for the required websites and count the visits. If the count exceeds the limit perform an action
storage + history: Add a listener to chrome.history.onVisited. If the visited site is from the required list, increment the visit count in storage. If the storage count exceeds the limit perform an action
Which of the above approaches has least impact on Chrome's browsing performance? Or, is there any another api(s) that I can use to achieve the same?
I would like my extension to consume least amount of user's battery :)
In 1 the extension will do a lot of unnecessary work when the user isn't using the browser.
In 2 the extension's background script will restart more often if the user navigates a lot but makes pauses between navigating for more than the lifetime duration of the service worker (30 seconds by default), which is a typical interaction scenario.
In both cases the bigger inherent problem of ManifestV3 for an extension such as yours that observes user activity is not what the extension does itself, but the extremely huge overhead to restart the background worker, which is automatically terminated after 30 seconds since the last observed event (or 5 minutes if you use waitUntil). Such pauses in user activity are typical when browsing/interacting so for many users the worker will restart hundreds of times a day. Starting the worker takes 50-100ms and stresses the CPU+memory+disk for the entire duration, while a typical time spent in a simple observation extension's code is just 1-2ms.
In other words, an extension that observes user activity, such as yours, is inherently 25-100 times less efficient in ManifestV3 than it would be in ManifestV2 with a persistent background script.
Solutions.
Prolong the service worker's lifetime to reduce the amount of its restarts as shown here. To avoid wasting memory for users that keep the browser open without using it for hours you can dynamically adjust the lifetime duration by measuring and averaging intervals between the events or offer an option to set the duration in your extension UI. Hopefully, in the future the browser will do it automatically, but it may take years before this feature is actually implemented and even then it will still likely restart the background script way too often.
Use chrome.webNavigation events with a URL filter for your sites so that the background script wakes up only when these specific URLs are visited. If the URLs are configured by the user, you will need to unregister the listener first (e.g. by making the listener a named global function), then register it with the new URL filter. You may still need to prolong the worker's lifetime if these URLs are visited a lot.

Python Dash table live updates: Any alternate to Interval?

I am making a dash board with a table using python dash. I want it to be updated every time i gather data in the backgroud. The problem is I cant use the dcc.Interval as my data gathering can take bit longer sometimes, so I cant set periodic updates.
Is there any other alternatives?
Can I use the change in table data itself as a trigger to fire callback again? I tried that, but below code is not working.
#app.callback(Output('table','data'),
Output('table', 'style_data_conditional'),
Input('table','data'))
def updateTable(ignore):
return get_data()
The table can't change itself, or it would just create an infinite loop.
Some options:
You could set the interval to much much larger, like every minute or 2 minutes
You could use a button to manually trigger an update each time the user clicks it
You could also look into using web sockets. See some examples here and here. That would require something external to be able to send a message to your Dash app, though

Node send text after X amount of time?

Let's say you have a parking meter app. User selects an amount of time and pays. 20 minutes before their time is up you want to send them a text via Twilio that their time is almost up. I'm not concerned about the payment or text part. What's the best way to do the timing aspect in Node that triggers the function that sends the text 20min before their time is up? Im aware of setTimeout, but is this a scalable method of handling this? IIRC, setTimeout doesn't execute at exactly the end of it's timer, but is dependant on when it can execute within the event loop. Let's assume you may need a couple hundred timers running at once and your server is realtively busy with other users triggering other callbacks and async functions. Also, the text doesn't necessarily have to be sent at exactly 20min before their time is up, a couple minutes margin of error would be acceptable. Thanks for any help!

Partial playback using playbackDuration/startTime in Google Cast Chrome API (v3)

I am trying to cast just a snippet of a file (say, only from 00:00:30 to 00:00:40) from a Chrome sender to the default receiver. Reading the API reference documentation documentation for LoadRequest, MediaInfo, and QueueItem, it seemed like I should be able to do this with some combination of these. In particular, the first queued item (loaded with CastSession#loadMedia) would need LoadRequest#currentTime set to the offset (30 seconds in my example above) and MediaInfo#duration set to the duration (10 seconds in my example), while subsequently queued items would set QueueItem#startTime and QueueItem#playbackDuration to the offset and duration (respectively).
However, this isn't happening in practice. I can confirm that the queue on the receiver has these fields set, but the no matter how I go about this, I can't get the right snippet to play. When I add the first media item as described above, the receiver just plays the track from beginning to end, neither respecting the offset nor the duration. Since the combination of LoadRequest#currentTime and MediaInfo#duration is a bit odd, I tried using only the QueueItem method (add the first media item with autoplay = false, add another queue item, remove the first, and then start playing the queue). In this case, the offset was still not respected, and the duration ended up being (very strangely) the sum of startTime and playbackDuration (in addition, any subsequently queued items would load, and then "finish" playing without starting, which I also can't figure out).
Does anyone else have experience with this part of the API? Am I reading the documentation incorrectly and what I'm doing just isn't supported, or am I just piecing things together incorrectly?
I am not sure I understand why you are attempting to use a queue with multiple items. First, the duration field is not what you think it is; it is not the duration of play back that you want, it is the total duration of the media that is being loaded, regardless of where you start or stop the playback. In fact, in most cases, you don't even need to set that; the receiver gets the total duration of the media when it loads he item, at least in the majority of the cases. The currentTime should work (if it is not, please file a bug on our SDK issue tracker) and alternatively, you can load a media (with autoplay off) and "seek" to the time you want and then play. To stop at a certain point, you need to monitor the the playback location and when it reaches that point, pause the playback.

JavaFX - How to wait without freezing the UI?

I know there are some questions about this topic but none of these helped me to find a solution.
I've got two Timeline Animations, I want to execute them after a delay of a few seconds. I'm gonna show you an example:
Every time I click my mouse, the Animation shall reset to its default delay time, let's say 5 seconds. If I'll do nothing the time's running away until it's zero. And when I reach the 0 seconds, the Animation has to start(). And so on.
Of course Thread.sleep() would make my UI freeze until the mission is done.
And I don't know whether I should use Thread, Task or other classes because the work is not that complex.
There are a bunch of ways to do it, but I'm not experienced in multithreading and I wanna learn to make it efficiently. Thank you guys a lot.
You can probably achieve what you want using
timeline.setDelay(...);
to specify a delay before the timeline starts,
timeline.setCycleCount(Animation.INDEFINITE);
to make it repeat indefinitely, and
timeline.playFromStart();
to make it start again from the beginning (after its specified delay).

Resources