Updating Azure Batch autoscale formula once pool exists - c#

I can create a pool with an autoscale formula fine. The code for this is as follows.
var pool = client.PoolOperations.CreatePool(poolName, vmsize, new CloudServiceConfiguration(osFamily, osVersion));
pool.TaskSchedulingPolicy = new TaskSchedulingPolicy(ComputeNodeFillType.Pack);
pool.AutoScaleFormula = autoscaleFormula;
pool.AutoScaleEnabled = true;
pool.AutoScaleEvaluationInterval = new TimeSpan(0, 0, 5, 0);
pool.Commit();
However if once the pool exists, I try and update the AutoScale formula, I get an error. The error is
{"The property AutoScaleFormula cannot be modified while the object is
in the Bound state."}
The code is
var client = BatchClient.Open(GetCloudSharedKeyCredentials(primary));
var pool = client.PoolOperations.GetPool(poolName);
pool.AutoScaleFormula = formula;
pool.AutoScaleEnabled = true;
pool.AutoScaleEvaluationInterval = new TimeSpan(0, 0, 5, 0);
pool.Commit();
This used to work before I updated to the latest version of the Azure Batch library. Has anyone got any experience of Azure Batch and can advise why I'm getting this error?

You can use the PoolOperations.EnableAutoScale method directly.
For your example, you could use the following:
var client = BatchClient.Open(GetCloudSharedKeyCredentials(primary));
client.Pooloperations.EnableAutoScale(poolName, formula, TimeSpan.FromMinutes(5));

Related

C# OpenTelemetry against Jaeger works in Simple but not Batch

Have a pretty much working environment to use for tracing, OpenTelemetry against Jaeger Tracing.
I sort of read that Batch for process is the preferred way then Simple. How ever with in .Net Framework 4.8 Batch dose not seem to give any results being logged.
I did a capture of packet data with Wireshark. Nothing happens when running in Batch.
Is there something with this configuration that is missing to have this as ExportProcessorType.Batch instead of ExportProcessorType.Simple?
public TracerProvider GetTracerProvider(string host, int port)
{
BackendServiceResource = ResourceBuilder.CreateDefault()
.AddService(Process.GetCurrentProcess().ProcessName)
.AddAttributes(new[]
{
new KeyValuePair<string, object>("MachineName", Environment.MachineName),
new KeyValuePair<string, object>("UserName", Environment.UserName),
});
return Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(BackendServiceResource)
.SetSampler(new AlwaysOnSampler())
.SetErrorStatusOnException(true)
.AddSource(ActivitySource.Name)
.AddConsoleExporter()
.AddJaegerExporter(jeager =>
{
jeager.AgentHost = host;
jeager.AgentPort = port;
jeager.MaxPayloadSizeInBytes = 4096;
jeager.ExportProcessorType = ExportProcessorType.Simple;
jeager.BatchExportProcessorOptions = new BatchExportProcessorOptions<Activity>()
{
MaxQueueSize = 2048,
ScheduledDelayMilliseconds = 5000,
ExporterTimeoutMilliseconds = 30000,
MaxExportBatchSize = 512,
};
})
.Build();
}
Thought I post a solution for this sort of issue.
The reason for these problems is because in some cases as application can close down before the process is fully completed. A solution for this is using and making sure that all gets completed before all is valid for closure.
You can read more about it more here https://github.com/open-telemetry/opentelemetry-dotnet/issues/2758

WWF: SqlWorkflowInstanceStoreBehavior verus SqlWorkflowInstanceStore

I have a Windows Service wrapping a WCF Service, which contains a WorkflowApplication, which runs Activities. I have also configured SQL Server 2008 Express (I know, it's approaching EOL, but the documentation explicitly states that only SQL Server 2005 or SQL Server 2008 are supported) to host the database and the connection works. To be even clearer: The entire process of the Activity completes and receives the return (I'm calling it via the WCF client wrapped in PowerShell).
The issue that I'm having is that I've configured SqlWorkflowInstanceStoreBehavior on the ServiceHost and SqlWorkflowInstanceStore on the WorkflowApplication. Neither of these throws a SQL exception but I think that the ServiceHost is taking precidence, as all that I can see is a singe entry on the LockOwnersTable.
Code from Windows Service:
this.obj = new ServiceHost(typeof(WorkflowService));
SqlWorkflowInstanceStoreBehavior instanceStoreBehavior = new SqlWorkflowInstanceStoreBehavior("Server=.\\SQL2008EXPRESS;Initial Catalog=WorkflowInstanceStore;Integrated Security=SSPI")
{
HostLockRenewalPeriod = TimeSpan.FromSeconds(5),
InstanceCompletionAction = InstanceCompletionAction.DeleteNothing,
InstanceLockedExceptionAction = InstanceLockedExceptionAction.AggressiveRetry,
InstanceEncodingOption = InstanceEncodingOption.GZip,
RunnableInstancesDetectionPeriod = TimeSpan.FromSeconds(2)
};
this.obj.Description.Behaviors.Add(instanceStoreBehavior);
this.obj.Open();
Code from WCF Service/WorkflowApplication:
SqlWorkflowInstanceStore newSqlWorkflowInstanceStore = new SqlWorkflowInstanceStore("Server=.\\SQL2008EXPRESS;Initial Catalog=WorkflowInstanceStore;Integrated Security=SSPI")
{
EnqueueRunCommands = true,
HostLockRenewalPeriod = TimeSpan.FromSeconds(5),
InstanceCompletionAction = InstanceCompletionAction.DeleteNothing,
InstanceLockedExceptionAction = InstanceLockedExceptionAction.BasicRetry,
RunnableInstancesDetectionPeriod = TimeSpan.FromSeconds(5)
};
InstanceHandle workflowInstanceStoreHandle = newSqlWorkflowInstanceStore.CreateInstanceHandle();
CreateWorkflowOwnerCommand createWorkflowOwnerCommand = new CreateWorkflowOwnerCommand();
InstanceView newInstanceView = newSqlWorkflowInstanceStore.Execute(workflowInstanceStoreHandle, createWorkflowOwnerCommand, TimeSpan.FromSeconds(30));
newSqlWorkflowInstanceStore.DefaultInstanceOwner = newInstanceView.InstanceOwner;
// Now stage the WorkflowApplication, using the SQL instance.
AutoResetEvent syncEvent = new AutoResetEvent(false);
WorkflowApplication newWorkflowApplication = new WorkflowApplication(unwrappedActivity)
{
InstanceStore = newSqlWorkflowInstanceStore
};
Questions:
Does the ServiceHost SqlWorkflowInstanceStoreBehavior override the SqlWorkflowInstanceStore on the WorkflowApplication? If so, the obvious answer would be to remove the SqlWorkflowInstanceStoreBehavior on the ServiceHost; however, as inferred before, I fear that will prove fruitless, as the WorkflowApplication currently isn't logging anything (or even attempting to, from what I can tell).
ASAppInstanceService seems specific to WindowsServer. Is is possible to host those (for dev/pre-production) on Windows 10, if the ServiceHost (via Windows Service option) is always going to block/disable the WorkflowApplication from making the SQL calls?
Figued out the answer:
newWorkflowApplication.Persist();

Live Chart is not rendering on Azure

I have followed the below mentioned link to generate an image of live graph in my application and it is working fine on my local machine but when I deploy it on azure it is not doing anything. I am getting an empty image that does not contains graph in it further I have checked in logs no error or exception is being thrown. It seems that it is not working on Azure.
https://github.com/beto-rodriguez/Live-Charts/blob/develop/Examples/Wpf/CartesianChart/Chart%20to%20Image/ChartToImageSample.xaml.cs
I can reproduce the issue on my local environment now by just commenting the following line of code:
myChart.Update(true, true); //force chart redraw
viewbox.UpdateLayout();
It seems that control cannot be updated on Azure. I have also tried to update the controls through "Dispatcher" but still getting the same issue on Azure.
Can anybody help me please?
I create a test sample on my side, I find the code that is used to generate image for LiveChart can work in Bot application on Azure.
Installed following LiveCharts and LiveCharts.Wpf NuGet
<package id="LiveCharts" version="0.9.7" targetFramework="net46" />
<package id="LiveCharts.Wpf" version="0.9.7" targetFramework="net46" />
Create a Bot Application project and Put the code of generating image for LiveChart in Bot Application (if possible, you can recreate a new Bot Application and test the following code to check if it works for you)
string sfp = "";
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
// calculate something for us to return
int length = (activity.Text ?? string.Empty).Length;
sfp = System.Web.HttpContext.Current.Server.MapPath($"~/IMG/chart.png");
Thread STAThread = new Thread(() =>
{
var myChart = new LiveCharts.Wpf.CartesianChart
{
DisableAnimations = true,
Width = 600,
Height = 200,
Series = new SeriesCollection
{
new LineSeries
{
Values = new ChartValues<double> {1, 6, 7, 2, 9, 3, 6, 5}
}
}
};
var viewbox = new System.Windows.Controls.Viewbox();
viewbox.Child = myChart;
viewbox.Measure(myChart.RenderSize);
viewbox.Arrange(new System.Windows.Rect(new Point(0, 0), myChart.RenderSize));
myChart.Update(true, true); //force chart redraw
viewbox.UpdateLayout();
SaveToPng(myChart, "chart.png");
});
STAThread.SetApartmentState(ApartmentState.STA);
STAThread.Start();
STAThread.Join();
await context.PostAsync($"You sent {activity.Text} which was {length} characters1");
context.Wait(MessageReceivedAsync);
}
Note: in my test, I create IMG folder manually via Kudu Console, not create it in code.
Test in Web Chat and send a message to Bot, and then check site folder, can find the image chart.png is generated via Kudu Console
chart.png
Besides, I send image as an attachment to client with the following test code, the chart.png can be rendered fine in client side.
var replymes = context.MakeMessage();
replymes.Attachments.Add(new Attachment()
{
Name = "chart.png",
ContentType = "image/png",
ContentUrl = "https://xxxx.azurewebsites.net/IMG/chart.png"
});
await context.PostAsync(replymes);

WF 4.5 bookmark and persistence in hosted web app

I developed workflow for an approval system. I used Bookmarks and
Persistence features to persist app state before unloading.
Workflow
Send an email to P1 for approval.
If P1 approved then next send next approval request to P2.
I am using WorkflowApplication class to invoke workflow from my asp.net application.
I am running my asp.net website on localhost (IIS Express).
I am not sure how do i handle Application shutdown, restart, scenarios
for my current workflow.
My code always hit app.run as first thing.
So, suppose, email to sent P1 for approval and meanwhile i stopped IIS Express/VS.
Now i launch web app again - app.run will again so i will lose previous persistence. right?
How i can make sure that workflow is running all the time on hosted application? on IIS server in actual environment? whenever workflow is invoked it should first check whether any previous state persisted? if yes then load that and run from that point?
Any link, help will be appreciated
My idea:
On web app restart when it comes to app.run, just check in persistence database and if any previous state persisted, read it out and put some logic to restart from that point.
But i really want to know, WF 4.5 does not handle self nicely? how workflowhostservice will help me in this case?
In my following code, i am calling app.run before resuming bookmark 1 and bookmark 2.
Code:
AutoResetEvent syncEvent = new AutoResetEvent(false);
Guid wfID;
ApprovalWorkflow appFlow = new ApprovalWorkflow
{
approvalStatus = "approved"
};
WorkflowApplication app = new WorkflowApplication(appFlow);
InstanceStore store = new SqlWorkflowInstanceStore(#"Data Source=.\SQLEXPRESS;Initial Catalog=WF45GettingStartedTutorial;Integrated Security=True");
InstanceHandle handle = store.CreateInstanceHandle();
InstanceView view = store.Execute(handle, new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));
handle.Free();
store.DefaultInstanceOwner = view.InstanceOwner;
app.InstanceStore = store;
app.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
{
return PersistableIdleAction.Unload;
};
app.Unloaded = delegate(WorkflowApplicationEventArgs e)
{
syncEvent.Set();
};
wfID = app.Id;
app.Run();
syncEvent.WaitOne();
// resume bookmark 1
appFlow = new ApprovalWorkflow { approvalStatus = "approved" };
app = new WorkflowApplication(appFlow);
app.InstanceStore = store;
app.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
{
return PersistableIdleAction.Unload;
};
app.Unloaded = delegate(WorkflowApplicationEventArgs e)
{
syncEvent.Set();
};
app.Load(wfID);
app.ResumeBookmark("B1", "test1");
syncEvent.WaitOne();
// resume bookmark 2
appFlow = new ApprovalWorkflow { approvalStatus = "approved" };
app = new WorkflowApplication(appFlow);
app.InstanceStore = store;
app.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
{
syncEvent.Set();
};
app.Unloaded = (workflowApplicationEventArgs) =>
{
syncEvent.Set();
};
app.Load(wfID);
app.ResumeBookmark("B2", "test");
syncEvent.WaitOne();
}

Initialize MongoClient with MongoClientSettings in C#

I'm trying to initialize the MongoClient from the Mongo 2.0 driver as follows:
MongoClientSettings settings = new MongoClientSettings();
settings.WaitQueueSize = int.MaxValue;
settings.WaitQueueuTimeout = new TimeSpan(0,2,0);
settings.MinConnectionPoolSize = 1;
settings.MaxConnectionPoolSize = 25;
settings.Server = new MongoServerAddress("mongodb://localhost");
client = new MongoClient(settings)
However, when I now try to insert a document with this code:
db = client.GetDatabase("local");
col = db.GetCollection<BsonDocument>(collectionName);
col.InsertOneAsync(new BsonDocument().Add(new BsonElement("id",BsonValue.Create(1)))).Wait();
It doesn't do anything. It doesn't get inserted, and no error message (although after a while a first chance exception of System.Timeout appears in the output). If I initialize the client with
client = new MongoClient("mongodb://localhost")
It does work and uploads the document as intended.
I want the client to be able to handle a very high write throughput, so I tried these settings first. Did I set some of the settings wrong or is there a different problem?
EDIT: After some more testing, it is indeed a System.Timeout exception I'm getting.
I could reproduce the problem, only in my error message, there is some much more helpful information buried somewhere in about 40 lines of text:
No such host is known
It turns out that MongoServerAddress only expects the hostname, not the protocol:
settings.Server = new MongoServerAddress("localhost");

Categories

Resources