.netcore webapi debugging pause - asp.net-core

I have a web api project which is a console application and the main looks like
public static void Main(string[] args)
{
// Get the current settings.
ThreadPool.GetMinThreads(out var minWorker, out var minIOC);
// Change the minimum number of worker threads to four, but
// keep the old setting for minimum asynchronous I/O
// completion threads.
if (ThreadPool.SetMinThreads(250, minIOC))
{
Logger.Info("The minimum number of threads was set successfully");
}
else
{
Logger.Error("The minimum number of threads was not changed");
// The minimum number of threads was not changed.
}
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>().Build();
}
When the debugger runs and paused it's always this line that is hit:
BuildWebHost(args).Run();
How do I make it pausing at the actual code being executed?
Edit
I'm pressing pause while some request is being executed and expect to see, for example, a call to the database when paused

While debugging open threads window (Debug->Windows->Threads). Once paused one of those threads will be the right worker with required call stack.

Related

Concurrent processing of Channels

I'm following this tutorial to create a hosted service. The program runs as expected. However, I want to process the queued items concurrently.
In my app, there are 4 clients, each of these clients can process 4 items at a time. So at any given time, 16 items should be processed in parallel.
So based on these requirements, I've modified the code a bit:
In the MonitorLoop class:
private int count = 0;
private async ValueTask MonitorAsync()
{
while (!_cancellationToken.IsCancellationRequested)
{
await _taskQueue.QueueAsync(BuildWorkItem);
Interlocked.Increment(ref count);
Console.WriteLine($"Count: {count}");
}
}
and in the same class:
if (delayLoop == 3)
{
_logger.LogInformation("Queued Background Task {Guid} is complete.", guid);
Interlocked.Decrement(ref count);
}
This shows that, if I set the "Capacity" as 4, the value will never increase after 5.
Basically, if the queue is full, it will wait until there's room for one more.
The problem is that the items are processed one at a time.
Here's the code for the BackgroundProcessing method on the QueuedHostedService class:
private async Task BackgroundProcessing(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var workItem = await TaskQueue.DequeueAsync(stoppingToken);
try
{
//instead of getting a single item from the queue, somehow, here
//we should be able to process them in parallel for 4 clients
//with a limit for maximum items each client can process
await workItem(stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error occurred executing {WorkItem}.", nameof(workItem));
}
}
}
I want to process them in parallel. I'm not sure if using Channel as the queue in the system is the best solution. Maybe I should have a ConcurrentQueue instead. But again, I'm not sure how to achieve a robust implementation that can have 4 clients with 4 threads each.
If you want four processors, then you can refactor the code to use four instances of your main loop, and use Task.WhenAll to (asynchronously) wait for all of them to complete:
private async Task BackgroundProcessing(CancellationToken stoppingToken)
{
var task1 = ProcessAsync(stoppingToken);
var task2 = ProcessAsync(stoppingToken);
var task3 = ProcessAsync(stoppingToken);
var task4 = ProcessAsync(stoppingToken);
await Task.WhenAll(task1, task2, task3, task4);
async Task ProcessAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var workItem = await TaskQueue.DequeueAsync(stoppingToken);
try
{
await workItem(stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error occurred executing {WorkItem}.", nameof(workItem));
}
}
}
}
I'm not sure how to achieve a robust implementation
If you want a robust implementation, then you can't use that tutorial, sorry. The primary problem with that kind of background work is that it will be lost on any app restart. And app restarts are normal: the server can lose power or crash, OS or runtime patches can be installed, IIS will recycle your app periodically, and whenever you deploy your code, the app will restart. And whenever any of these things happen, all in-memory queues like channels will lose all their work.
A production-quality implementation requires a durable queue at the very least. I also recommend a separate background processor. I have a blog series on the subject that may help you get started.

Analog of TestNG Reporter.getOutput() in Spock

I run API tests using Groovy and Spock.
Request/response data, produced by third-party libraries, appear in the system out (I see it in the Jenkins log).
Question:
what is the proper way to start-stop system out recording for each test iteration to some list of strings?
TestNG has Reporter.getOutput(result) which returns all log entries, appeared while test iteration run.
Is it something similar in Spock?
Am I right assuming it should be some implementation of Run listener where I start recording in beforeIteration() and attach it to report in afterIteration()?
Solved by using the OutputCapture from
spring-boot-starter-test
The sample of RunListener:
class RunListener extends AbstractRunListener {
OutputCapture outputCapture
void beforeSpec(SpecInfo spec) {
Helper.log "[BEFORE SPEC]: ${spec.name}"
outputCapture = new OutputCapture()
outputCapture.captureOutput() //register a copy off system.out, system.err streams
}
void beforeFeature(FeatureInfo feature) {
Helper.log "[BEFORE FEATURE]: ${feature.name}", 2
}
void beforeIteration(IterationInfo iteration) {
outputCapture.reset() //clear the stream copy before each test iteration
}
void afterIteration(IterationInfo iteration) {
}
void error(ErrorInfo error) {
//attach the content of copy stream object to the report if test iteration failed
Allure.addAttachment("${error.method.iteration.name}_console_out", "text/html", outputCapture.toString(), "txt")
}
void afterFeature(FeatureInfo feature) {
}
void afterSpec(SpecInfo spec) {
outputCapture.releaseOutput()
}
}
Shortly:
CaptureOutput is an implementation of Output Stream which logs in both initial out and copy stream object. The copy gets cleared in beforeIteration() and is attached to the report in afterIteration() in RunListener, so each test receives its own part of output.

How altbeacon is keeping a background service alive?

I am running into a issue that is the opposite problem of this thread:
AltBeacon not detect beacon when app is closed
I have an app that uses altbeacon (http://altbeacon.org/)
The app initializes the alt-beacon implementing the interfaces at the application level as below (details omitted)
public class MyApp extends Application implements
BootstrapNotifier,
BeaconConsumer {
//some code
#Override
public void onCreate() {
super.onCreate();
initBeacons();
}
public void initBeacons() {
mBackgroundPowerSaver = new BackgroundPowerSaver(this);
org.altbeacon.beacon.BeaconManager altBeaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
altBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
// estimote
altBeaconManager.setBackgroundScanPeriod(5000);
altBeaconManager.setBackgroundBetweenScanPeriod(25000);
mBeaconManager = MyBeaconManager.getInstance(this, altBeaconManager);
mRegionBootstrap = new RegionBootstrap(this, MyBeaconManager.getRegions());
altBeaconManager.bind(this);
}
#Override
public void onBeaconServiceConnect() {
Thread thread = new Thread() {
public void run() {
// Try range the beacons
rangeMyBeacons();
}
};
thread.start();
}
#Override
public void didEnterRegion(Region region) {
// Some code
}
#Override
public void didExitRegion(Region region) {
// Some code
}
#Override
public void didDetermineStateForRegion(int i, Region region) {
// Some code
}
public class MyBeaconManager implements
RangeNotifier {
// some code
However, If I kill the app or restart the phone, without any special broadcasts or app permissions the alt-beacon service comes back alive. Alt-beacon re-starts itself all the time, in other words. Notice that I don't have any foreground services running. Here' is a screenshot of the app after several hours (and I rebooted the phone), with all apps closed. You can see the alt-beacon is alive and scanning the beacons.
yet when I look at alt-beacon code, it is not a foreground service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
LogManager.i(TAG,
intent == null ?
"starting with null intent"
:
"starting with intent " + intent.toString()
);
return super.onStartCommand(intent, flags, startId);
}
I did search inside the library and I see not hits to START_REDELIVER_INTENT or START_STICKY.
My question is how does alt-beacon keep the service alive when the app is killed?
The reason I want to understand this feature is that I am writing a similar service but I can only get it do work as alt-beacon if I wrap it into a foreground service. Everything else I tried, the service gets killed as soon as the app closes.
thank you.
The Android Beacon Library uses an AlarmManager to keep the scanning service running in the background. It periodically sets an alarm for 5 minutes in the future, which causes the operating system to deliver it a BroadcastIntent which will start the scanning service if stopped. When running, the library continually reschedules this alarm.
You can see the code that does that here:
https://github.com/AltBeacon/android-beacon-library/blob/master/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScanner.java#L339
// In case we go into deep sleep, we will set up a wakeup alarm when in the background to kickoff
// off the scan cycle again
protected void setWakeUpAlarm() {
// wake up time will be the maximum of 5 minutes, the scan period, the between scan period
long milliseconds = 1000l * 60 * 5; /* five minutes */
if (milliseconds < mBetweenScanPeriod) {
milliseconds = mBetweenScanPeriod;
}
if (milliseconds < mScanPeriod) {
milliseconds = mScanPeriod;
}
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + milliseconds, getWakeUpOperation());
LogManager.d(TAG, "Set a wakeup alarm to go off in %s ms: %s", milliseconds, getWakeUpOperation());
}
This design ensures that if the app needs to be terminated due to low memory, scanning will be restarted five minutes in the future. This allows the phone time to complete the memory intensive operation, while still allowing beacon detections in a reasonable time frame.

Can I have per AppDomain Environment Variables in C#/.net?

In a multi appdomain setup, is there a way to make SetEnvironementVariables and Get.... work within the appdomain only, so each appdomain can have different values for the same variable?
No. :(
This example:
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var newDomain = AppDomain.CreateDomain("Alternative");
Proxy proxyObj = (Proxy)newDomain.CreateInstanceAndUnwrap(typeof(Proxy).Assembly.GetName().FullName,
typeof(Proxy).FullName);
Environment.SetEnvironmentVariable("HELLO_MSG", "Hello World", EnvironmentVariableTarget.Process);
proxyObj.ShowEnvironmentVariable();
Console.ReadKey();
}
}
class Proxy : MarshalByRefObject
{
public void ShowEnvironmentVariable()
{
var msg = Environment.GetEnvironmentVariable("HELLO_MSG");
Console.WriteLine(String.Format("{0} (from '{1}' AppDomain)", msg, AppDomain.CurrentDomain.FriendlyName));
}
}
}
Will output:
Hello World (from 'Alternative' AppDomain)
The process is the most specific level of encapsulation for environment variables, and AppDomains will still "live inside" the same process.
Note that this will happen for all other process-level information (such as Directory.GetCurrentDirectory(), command-line args, etc.
One possible solution would create worker processes (".exe" applications spawned from the main process), but that will certainly add some complexity to your application.

WCF Async - How to use ManualResetEvent

Can any one tell me how to use 'ManualResetEvent' in a async wcf service? I have a console application which makes calls to async wcf service and I wanted to close the console app after 'oncomplete' event finishes.
If possible please provide me a sample.
Thanks in advance.
You'd write your Console App something like the following:
class Program
{
static ManualResetEvent exitEvent = new ManualResetEvent(false); // Create the wait handle
static void Main()
{
using(var client = CreateYourClient())
{
client.MethodCompleted += MethodCompleted;
client.MethodAsync(); // Start method
exitEvent.WaitOne(); // Block until the method is done...
}
}
static void MethodCompleted(object sender, MethodCompletedEventArgs args)
{
// Do your work...
// At this point, signal that the console can close...
exitEvent.Set();
}
}
However, if you're just doing a single method call, it's probably better to just make it synchronous. This would only really be beneficial if you're calling multiple asynchronous methods simultaneously.