Run a background wcf service call in MVC applicaiton - multithreading

In my MVC web application, I use a WCF services.
Once the user sign In, I need to update the "lastLoggedOnDate" for the user as a background WCF service call.
I want the user login process to be completed and not wait for this service call.
How can I do this?
Person personObj = null;
using (var services = new ServiceFactory())
{
personObj = services.Person.GetUserByLoginDetails(user.Username,-parameters-);
}
--Authentication process --
--If authentication success --
--BACKGROUND CALL TO WCF service ??

In case the background task spans the boundary of a single HTTP request/response, there are at least two options to deal with this:
Delegate the pending task to a separate process like Windows Service (a similar question).
Create a static task scheduler (singleton object), which would run the task inside the ASP.NET process space. More details: Long Running Background Tasks in Asp.Net MVC3.

Related

azure logic apps: waiting for an ACI container to terminate to get its logs

I have an Azure logic app that correctly creates an Azure Container Instance. The container starts, does its job and terminates. I need to collect its logs with the appropriate connector and write them to an azure blob.
I have all the pieces in place but I do not know how to wait for the container to terminate before using the "get logs of container" connector to collect logs.
If the container job would last a predictable amount of time, I could use the Delay connector before getting the logs and it would suffice (I've tried with short jobs and it works well).
But my jobs may last several hours, depending on some external factors, so the Delay technique does not work.
I've tried with the "Until" connector, together with delay and the "get properties of a container group" container to wait until the state of the container is not "terminated", but without success (maybe I did it wrong). Anyway this can be quite expensive, since every "check" is billed.
How can I wait for the container to terminate before asking for its logs?
thanks.
starting from Charles Xu's answer, the correct sequence when setting the variable is
this uses the "state" container instance variable instead of "provisioning state". The latter is about the creation of the container group, the first is about the state of the container instance, which is what I need.
I added a delay to decrease the number of (paid) runs of the connector.
If you want to get the logs of a container group and nobody knows when it can terminate. In the logic app, you can use a variable to store the state of the container group and then use an until control the loop which will get the terminate of the container group until it comes true.
Here are the steps:
Create a container group;
Get the provision state of the container group;
Initialize a variable to store the provision state of the container group;
In the untile, get the provision state of the container group until the state is equal to terminate;
Get the logs of the container group.
The whole structure:
The Initialize variable and Until steps:
Since you mentioned using "Until" in logic app maybe expensive, here I provide another solution for your reference.
We can create a time trigger azure function and set the cron expression every 1 minutes, create a service plan(free tier) for the function, so we don't need to pay for the running cost of the function(but may pay for the storage of the function).
The function will run every 1 minute. In function we need to get the properties of the container by using this rest api and then if the state is "terminated", call the logic app request to trigger the logic app(the logic app should be created as "When a HTTP request is received").
The function code(in local, before deployed to azure) should be as below:
using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
namespace hurytimeFun
{
public static class Function1
{
[FunctionName("Function1")]
public static void Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
//1. using rest api to get the properties of your container
//2. if the state is "terminated"
// call the logic app request to trigger the logic app
}
}
}
Hope it would be helpful to your problem~
Once a container terminates, everything is lost. You could install the log-analytics-containers from the Azure marketplace for logging and log before the container terminates

How To migrate windows service in Azure service fabric

I want to migrate typical windows service which is written in .net to Azure using Service fabric.
To implement this , I am creating one service fabric application containing one micro service as guest executable which uses .exe of windows service and deploying application package to service fabric cluster.
After deploying service fabric application on cluster I want windows service should install & start automatically on all nodes however at any time application is running on any single node. I want windows service should run on only one node at a time.
Please kindly help to implement this.
You can certainly run your service as a guest executable. Making sure it only runs on one node can be done by setting the instance count to 1 in the manifest, like so:
<Parameters>
<Parameter Name="GuestService_InstanceCount" DefaultValue="-1" />
</Parameters>
...
<DefaultServices>
<Service Name="GuestService">
<StatelessService ServiceTypeName="GuestServiceType"
InstanceCount="[GuestService_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
Or, you could actually migrate it, not just re-host it in the SF environment...
If your Windows Service is written in .NET and the you wan't to benefit from Service Fabric then the job of migrating the code from a Windows Service to a Reliable Service in Service Fabric should not be to big.
Example for a basic service:
If you start by creating a Stateless Service in a Service Fabric application you end up with a service implementation that looks like (comments removed):
internal sealed class MigratedService : StatelessService
{
public MigratedService(StatelessServiceContext context)
: base(context)
{ }
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[0];
}
protected override async Task RunAsync(CancellationToken cancellationToken)
{
// TODO: Replace the following sample code with your own logic
// or remove this RunAsync override if it's not needed in your service.
long iterations = 0;
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
ServiceEventSource.Current.ServiceMessage(this.Context, "Working-{0}", ++iterations);
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
}
}
The RunAsync method starts running as soon as the Service is up and running on a node in the cluster. It will continue to run until the cluster, for some reason, decides to stop the service, or move it to another node.
In your Windows Service code you should have a method that is run on start. This is usually where you set up a Timer or similar to start doing something on a continuous basis:
protected override void OnStart(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 60000; // 60 seconds
timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
timer.Start();
}
public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
...
DoServiceStuff();
Console.WriteLine("Windows Service says hello");
}
Now grab that code in OnTimer and put it in your RunAsync method (and any other code you need):
protected override async Task RunAsync(CancellationToken cancellationToken)
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
DoServiceStuff();
ServiceEventSource.Current.ServiceMessage(this.Context,
"Reliable Service says hello");
await Task.Delay(TimeSpan.FromSeconds(60), cancellationToken);
}
}
Note the Task.Delay(...), it should be set to the same interval as your Windows Service had for it's Timer.
Now, if you have logging in your Windows Service and you use ETW, then that should work out of the box for you. You simply need to set up some way of looking at those logs from Azure now, for instance using Log Analytics (https://learn.microsoft.com/en-us/azure/log-analytics/log-analytics-service-fabric).
Other things you might have to migrate is if you run specific code on shut down, on continue, and if you have any parameters sent to the service on startup (for instance connection strings to databases). Those need to be converted to configuration settings for the service, look at SO 33928204 for a starting point for that.
The idea behind service fabric is so that it manages your services, from deployment and running. Once you've deployed your service/application to the service fabric instance it will be just like running a windows service (kinda) so you wont need to install your windows service. If you're using something like TopShelf you can just run the exe and everything will run totally fine within service fabric.

How to host a worker role and web role in a single cloud service with just one instance?

We have a project which has one web role(WCF Service) and one worker role. The worker role uses on an average 0.34% of the resources. We would like to host both the WCF and worker role in a single cloud service with a single instance. How can this be done? For now, the worker role and WCF service each use one instance.
Nothing wrong with Sandrino's answer, but from the question, it doesn't look like any threading is required. My answer is to just move everything from WorkerRole.cs in the worker role into WebRole.cs in the web role.
You can use a ThreadedRoleEntryPoint for this:
public class WebRole : ThreadedRoleEntryPoint
{
...
public override void Run()
{
List<WorkerEntryPoint> workers = new List<WorkerEntryPoint>();
workers.Add(new MyWorkerRole());
base.Run(workers.ToArray());
}
}
Instead of inheriting from the default RoleEntryPoint you can use the ThreadedRoleEntryPoint, which allows you to pass a list of workers that it should start as a background thread. This way you can save resources by hosting one or more WorkerRoles as a thread in the WebRole.

How can I test multiple Web Role instances in Windows Azure?

Background: I've deployed an MVC3 application to 2 Azure Web Role instances, but I'm confused as to how I can test out the possibility of one of these instances failing.
Is there a way that I can test to ensure that my Web Role code works seamlessly when one of my instances is taken offline?
Can I manually stop one of them? Or somehow configure the load balancer to force all traffic to one of the servers?
Thanks!
If you have RDP access enabled to your instances you can very easily remove one or more instance out from LoadBalancer even when the instance is running healthy without writing any line of code. You just need to RDP to your instance and then use PowerShell scripts to take the instance off from loadbalancer. In my following blog I have described the exact procedure:
http://blogs.msdn.com/b/avkashchauhan/archive/2012/01/27/windows-azure-troubleshooting-taking-specific-windows-azure-instance-offline.aspx
The above details also help to run load testing by removing N instances from total M instances .
If you use the StatusCheck event to set the status to Busy, your instance won't receive any more requests from the loadbalancer. You might want to write some code to send messages to your instances that will set them as busy for some time (using queues for example).
public override bool OnStart()
{
RoleEnvironment.StatusCheck += RoleEnvironmentStatusCheck;
return base.OnStart();
}
// Use the busy object to indicate that the status of the role instance must be Busy
private volatile bool busy = true;
private void RoleEnvironmentStatusCheck(object sender, RoleInstanceStatusCheckEventArgs e)
{
If (this.busy)
{
// Sets the status of the role instance to Busy for a short interval.
// If you want the role instance to remain busy, add code to
// continue to call the SetBusy method
e.SetBusy();
}
}
Reference: http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.serviceruntime.roleenvironment.statuscheck.aspx
Besides that you can also simply reboot your instance (using the Windows Azure portal or Remote Desktop).
Steve Marx (aka smarx) developed a tool called WazMonkey. It is the azure counterpart of the tool Chaos Monkey developed by the netflix team to simulate broken instances in amazon AWS. WazMonkey terminates instances of a windows azure cloud service randomly to test the resilience of a cloud applications.

Azure Worker Role Control Start Stop and Status

I'm doing my first project but large one on developing Azure Application with Intergration Component.
Currently most of the integration are done using SSIS Packages and would like to transform them on to Worker Role in Azure.
Could someone please help me to understand the following queries regarding Worker Role please?
Is there way to start or stop the Worker role (just like SSIS or Windows Schedulers) via GUI? If not how to achieve this?
How do I know my worker role has been running or not running (including why it's not running ie. logs)
How do I spin multiple worker role based on time (i.e. (9:00AM to 11:00AM spin 4 roles and scale down on quiet period)
Does the following code creates any poison message or dead lock (if multiple there are 10,000 messages to process and every 5 seconds the new thread (Processsing.run) is started?
while(true)
{
var thread = new Thread(Run);
thread.start();
Thread.Sleep(5000);
Trace.WriteLine("Working", "Information");
}
public class PhotoProcessing
{
public static void Run()
{
// Read from queue
CloudQueueMessage msg =
Storage.Queue.GetNextMessage();
while(msg != null)
{
string[] message = msg.AsString.Split('$');
if(message.Length == 2)
{
AddWatermark(message[0], message[1]);
}
// Message has been read so remove it
Storage.Queue.DeleteMessage(msg);
// Get next message if any
msg = Storage.Queue.GetNextMessage();
}
}
Is there way to start or stop the Worker role (just like SSIS or Windows Schedulers) via GUI? If not how to achieve this?
There are actually many ways to achieve this. You can use Windows Azure Portal to do or you could use 3rd party tools (like our Cloud Storage Studio) or you could write your own application using Windows Azure Service Management API (http://msdn.microsoft.com/en-us/library/ee460799.aspx)
How do I know my worker role has been running or not running (including why it's not running ie. logs)
Again you could use one of the GUI based tools to see the status of your roles. As far as why the roles are not running, you would need to enable Windows Azure Diagnostics in your worker role (http://msdn.microsoft.com/en-us/library/gg433048.aspx)
How do I spin multiple worker role based on time (i.e. (9:00AM to 11:00AM spin 4 roles and scale down on quiet period)
You can write your own application using Windows Azure Service Management API to do so or you could make use of 3rd party tools like AzureWatch from Paraleap or Azure Management Cmdlets (both from Microsoft and our company). While the cmdlets will get the job done, I believe Azure Watch is much more sophisticated solution. We wrote a blog post for autoscaling some days back which you can find here: http://www.cerebrata.com/Blog/post/Scale-your-Windows-Azure-instances-with-Azure-Management-Cmdlets.aspx.

Resources