How to update service worker version of my subscribers? - push-notification

i use minishlink/web-push for send pushes. And i make a service worker serviceworker.js for push messages, with push, notificationclick and notificationclose events listener.
To the site where the subscription takes place a have sw.js:
let timeStampInMs = new Date().getTime();
importScripts('https://super-push-site.com/serviceworker.js?ts=' + timeStampInMs);
It works fine.
But i make a new version of service worker and place it on old place (https://super-push-site.com/serviceworker.js).
How to update service worker version of my subscribers without their visit to the site where the subscription takes place?

Before answering your question, I would like to note that it's considered a bad practice to add a cache-buster parameter to your service worker URL, since the browser will already enqueue the new service worker for installation if it's byte-different to the existing service worker. You may read more about this on: The Service Worker Lifecycle
Now, to answer your actual question:
You can manually trigger the update by calling the update() method of your service worker registration, when a push message is received:
self.addEventListener('push', function (event) {
...
event.waitUntil(
Promise.all([
self.registration.showNotification(title, options);
self.registration.update()
])
);
});
You may also want to trigger self.registration.update() only if there actually is a newer version of the service worker available. To do that:
Store the version identifier of your SW in a variable.
Always send the latest SW version identifier within your push message payload.
Compare the two and trigger self.registration.update() if they don't match.
Hope this helps!

Related

Receive service bus message queue/topics in web api

I am working on a microservice based application in azure. My requirement is I had a service bus and I need to consume that service bus message in web api. Currently I implemented through azure functions, but my company asked to use api. Is it possible?, If possible please show me how to do it
You can create Background service to listen to message from service bus queue.
Below are few key points that needs to be noted:
Background task that runs on a timer.
Hosted service that activates a scoped service. The scoped service can use dependency injection (DI).
Queued background tasks that run sequentially.
App Settings:
1. {
2. "AppSettings": {
3. "QueueConnectionString": "<replace your RootManageSharedAccessKey here>",
4. "QueueName": "order-queue"
5. }
6. }
You can refer to c-sharpcorner blog for step by step process.
There is a simple way to get a simple message.
ServiceBusClient client = new ServiceBusClient("Endpoint=sb://yourservicesbusnamespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=Your_SharedAccess");
var receiver = client.CreateReceiver("Your Queue");
var message = await receiver.ReceiveMessagesAsync(1);
string ascii = Encoding.ASCII.GetString(message.FirstOrDefault().Body);
Console.WriteLine("Received Single Message: " + ascii);
await receiver.CompleteMessageAsync(message.FirstOrDefault());
I did some modifications from this post
https://ciaranodonnell.dev/posts/receiving-from-azure-servicebus/

Is there a way that a Party can be notified that a Flow has been completed?

Taking as an example the flow described in the Corda documentation (see here), how can Bob receive the notification that the transaction he just signed has been completed, without polling his own vault?
Does a specific callback exist?
I need that the CorDapp running on Bob node communicates to another system the status of the transaction in real-time
Thanks a lot
Two ways you could achieve this:
1. Subscribe to update using Client
cordaRPCOPS.vaultTrack(<YourState>.class).getUpdates().subscribe( update -> {
update.getProduced().forEach(stateAndRef -> {
// Action to be Performed on State Update
});
});
2. Subscribe to update using CordaService:
getServiceHub().getVaultService().trackBy(<YourState>.class).getUpdates().subscribe( update -> {
update.getProduced().forEach(stateAndRef -> {
// Action to be Performed on State Update
});
});
In addition to Ashutosh's answer,
Inside a SpringBoot webserver that identifies an API to start your flow, you can use proxy.startTrackedFlowDynamic() (where proxy is your node's RPC connection); it returns a FlowProgressHandle which you can use to subscribe to flow events.

How to deduplicate events when using RabbitMQ Publish/Subscribe Microservice Event Bus

I have been reading This Book on page 58 to understand how to do asynchronous event integration between microservices.
Using RabbitMQ and publish/subscribe patterns facilitates pushing events out to subscribers. However, given microservice architectures and docker usage I expect to have more than once instance of a microservice 'type' running. From what I understand all instances will subscribe to the event and therefore would all receive it.
The book doesn't clearly explain how to ensure only one of the instances handle the request.
I have looked into the duplication section, but that describes a pattern that explains how to deduplicate within a service instance but not necessarily against them...
Each microservice instance would subscribe using something similar to:
public void Subscribe<T, TH>()
where T : IntegrationEvent
where TH : IIntegrationEventHandler<T>
{
var eventName = _subsManager.GetEventKey<T>();
var containsKey = _subsManager.HasSubscriptionsForEvent(eventName);
if (!containsKey)
{
if (!_persistentConnection.IsConnected)
{
_persistentConnection.TryConnect();
}
using (var channel = _persistentConnection.CreateModel())
{
channel.QueueBind(queue: _queueName,
exchange: BROKER_NAME,
routingKey: eventName);
}
}
_subsManager.AddSubscription<T, TH>();
}
I need to understand how a multiple microservice instances of the same 'type' of microservice can deduplicate without loosing the message if the service goes down while processing.
From what I understand all instances will subscribe to the event and
therefore would all receive it.
Only one instance of subscriber will process the message/event. When you have multiple instances of a service running and subscribed to same subscription the first one to pick the message will set the message invisible from the subscription (called visibility timeout). If the service instance is able to process the message in given time it will tell the queue to delete the message and if it's not able to process the message in time , the message will re-appear in queue for any instance to pick it up again.
All standard service bus (rabbitMQ, SQS, Azure Serivce bus etc) provide this feature out of box.
By the way i have read this book and used the above code from eShotContainers and it works the way i described.
You should look into following pattern as well
Competing Consumers pattern
Hope that helps!

Remote Config implemented at rnfirebase have a mandatory subscription?

Initially I implemented the exactly Remote Config example from that link:
https://rnfirebase.io/docs/v3.3.x/config/example
firebase.config().fetch()
.then(() => {
return firebase.config().activateFetched();
})
.then((activated) => {
if (!activated) console.log('Fetched data not activated');
return firebase.config().getValue('hasExperimentalFeature');
})
.then((snapshot) => {
const hasExperimentalFeature = snapshot.val();
if(hasExperimentalFeature) {
enableSuperCoolFeature();
}
// continue booting app
})
.catch(console.error);
My idea is not subscribe the Remote Config. I just would like to know if it have any changes at APP startup (componentWillMount).
But I see that using that code above the Remote Config variables are not updating at a new APP startup. I searched and found that info about 12 hours cache:
Remote Config caches values locally after the first successful fetch
request. By default the cache expires after 12 hours, but you can
change the cache expiration for a specific request by passing the
desired cache expiration, in seconds, to
fetchWithExpirationDuration:completionHandler: (on iOS) or fetch (on
Android).
They also NOT recommend to change that cache to a small value:
Note that if you reduce this expiration time to a very small value,
you might start hitting the client-side throttling limit, which
prevents your client from making a fetch request more than a few times
per hour.
https://firebase.google.com/support/faq/#remote-config-requests
BUT, as I have to update values at APP startup, I decided to not follow this recommendation and test. In my tests using firebase.config().fetch(0)(fetch 0 to avoid cache) the APP apparentely is not subscribing the Remote Config. There are no listeners at javascript side.
So, could I continue using firebase.config().fetch(0) without worry? The update only occurs when code runs?
How is the internal implementation of firebase.config().fetch() / snapshot?
Using cache timeout of 0 seconds is only meant for development purposes. This will not work for you in production.
As per the documentation, you can fetch 5 times in a 60 minute window - before getting throttled by the client SDK.
Does that work for you?

Set time for scheduled task via ASP.NET

I have to solve the following problem. We got an ASMX web service which is requested every two minutes. If this service is not requested for ten minutes an email should be sent. We want to realize this by using the scheduled tasks. We imagined it like this
1. Creating a scheduled task which will send an email every ten minutes
2. If the service is requested the execution time for the task will be set to ten minutes from now and so the execution time cannot be reached
- If the service is not requested the execution time will be reached and the email is sent
Is there a way to solve this in ASP.NET or are there maybe better solutions?
Thanks for any response.
You may want to take a look at the Revalee open source project.
You can use it to schedule web callbacks at specific times. In your case, you could schedule a web callback (10 minutes in the future) every time your web service is used. When your web service receives the callback, it can determine whether or not the service has been used recently. If the web service has been active, then the callback is ignored; if the web service has been inactive, then it can send out an email message.
For example using Revalee, you might:
Register a future (10 minutes from now) callback when your application launches.
private DateTimeOffet? lastActive = null;
private void ScheduleTenMinuteCallback()
{
// Schedule your callback 10 minutes from now
DateTimeOffset callbackTime = DateTimeOffset.Now.AddMinutes(10.0);
// Your web service's Uri
Uri callbackUrl = new Uri("http://yourwebservice.com/ScheduledCallback/YourActivityMonitor");
// Register the callback request with the Revalee service
RevaleeRegistrar.ScheduleCallback(callbackTime, callbackUrl);
}
Anytime your web service is used, you register another callback and store the date & time that your service was active as a global value.
lastActive = DateTimeOffset.Now;
ScheduleTenMinuteCallback();
Finally, when the web schedule task activates and calls your application back, then you test the value of the global
private void YourActivityMonitor()
{
if (!lastActive.HasValue || lastActive.Value <= DateTimeOffset.Now.AddMinutes(-10.0))
{
// Send your "10 minutes has elapsed" email message
}
}
I hope this helps.
Disclaimer: I was one of the developers involved with the Revalee project. To be clear, however, Revalee is free, open source software. The source code is available on GitHub.

Resources