I inherited a project that uses custom performance counters to monitor number of successful/failed requests and their processing time for an IIS deployed web service. Code I used to log counters is like below:
using (var performanceCounter = new PerformanceCounter() { CategoryName = MyConstants.Constants.PerformanceCountersRootName, CounterName = counterName, MachineName = "." })
{
performanceCounter.ReadOnly = false;
if (operationCounter != OperationCounter.ProcessingTime)
{
performanceCounter.Increment();
}
else
{
performanceCounter.RawValue = value;
}
}
Now my question is how could I reset counters after a fixed period of time, say once every week. Here is a similar question, but my problem is I don't want to reset counters using code.
I need to do so using some scheduling mechanism, may be some sort of powershell script or windows schedule or something of this sort.
I have checked this answer and I don't feel this to be approach for me. Please suggest.
Thank You
Ravi
Related
I am a developer who has no load test experience and would like to learn how to do this.
I have a simple client server application where the client sends a request to the server and the server sends a response back.
I would like to load test this but I am not sure how to do this. Here is my GetResponse method which receives a response from the server.
Response GetResponse(Request request)
{
string data = Newtonsoft.Json.JsonConvert.SerializeObject(request);
System.Net.WebClient wb = new System.Net.WebClient();
string response = wb.UploadString("http://localhost:8080", data);
return Newtonsoft.Json.JsonConvert.DeserializeObject<Response>(response);
}
My initial thoughts are to write a routine to send a load of get response requests all at the same time and then try and monitor the CPU ticks or other to see how it is performing.
Can anyone let me know if this is the correct way to go about it? I am also not really sure what the best stats to gather are?
Thanks in advance
EDIT....
Whist waiting for an answer I have written the following which adds a new thread and processes the requests as desired. Please can you comment on whether this is sufficient to see what I need or do I need a proper load testing tool?
DateTime startTime;
DateTime endTime;
Console.WriteLine("Test how many concurrent users?");
string users = Console.ReadLine();
int usersCount;
if (int.TryParse(users, out usersCount) && usersCount > 0)
{
startTime = DateTime.Now;
_countDown = new CountdownEvent(usersCount);
for (var i = 0; i < usersCount; i++)
{
string userName = string.Format("user{0}", i);
Task.Factory.StartNew(() => TestRun(userName));
}
_countDown.Wait();
endTime = DateTime.Now;
Console.WriteLine("All tasks are completed!");
Console.WriteLine(string.Format("Av time(ms) per user: {0}", (endTime - startTime).TotalMilliseconds / usersCount));
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
public static void TestRun(object userName)
{
Thread newThread = new Thread(DoWork);
newThread.Start(userName);
}
public static void DoWork(object userName)
{
LoadTest.Test(userName.ToString());
_countDown.Signal();
}
First of all you need a load testing tool. If your Visual Studio license allows, the most straightforward option would be using MS VS Load Testing Framework. If you don't have Web and Load test types - there is a number of free and open source load testing tools.
Creating test itself. Being a developer you should know how to construct HTTP Request. If not - most load testing tools offer record and replay functionality.
Once you get load test working you can start ramping up the number of virtual users and keep an eye on associated metrics and KPIs, i.e. :
Number of concurrent users vs response time
Number of concurrent users vs throughput
Transactions per second
Server hits per second
Response Time:
Average
Median
90/95/99 Percentile
What is the maximum number of concurrent users / requests per second your application is able to serve without errors and having reasonable response time
If application is overloaded and does not respond does it return to normal operating mode when the load decreases
Analysing above metrics you can:
determine maximum performance and capacity of your application
identify the bottleneck and work it around if possible
i have this piece of code to detect a Process:
private Boolean IsGameRunning()
{
Process[] game = Process.GetProcesses();
foreach (Process process in game)
{
if (process.ProcessName.Contains("GameWindow"))
{
return true;
}
}
return false;
}
Since the code has to run a lot of times because it is inside a Timer, is there any way to improve the speed of the process?
I do not have any control over the game.
This code is inside a timer always enabled with an interval of 2000-3000 ms:
if (IsGameRunning())
{
Do stuff
}
else
{
Status("Waiting for game to start");
}
Given that the process is launched by another, in this case Steam, we can narrow the list to search to only child processes.
First, need to get the parent process id (PID).
var parentProcess = Process.GetProcesses().FirstOrDefault(x => x.ProcessName == "Steam");
Then using the Windows Management Instrumentation (accessed using the System.Management.dll), you can then search only the child processes.
bool IsGameRunning(int parentProcess, string childExecutableName)
{
var query = string.Format("SELECT * FROM Win32_Process WHERE ParentProcessId = {0} AND Name = '{1}'", parentProcess, childExecutableName);
using (var searcher = new ManagementObjectSearcher(query))
using (var results = searcher.Get())
{
return (results.Count > 0);
}
}
e.g. IsGameRunning(parentProcess.Id, "SuperMeatBoy.exe")
No guarantee that this is faster as I haven't done any comparative testing, however from prior experience using the WMI is more performant than iterating a list of processes.
If you want to go further, a more advanced solution would be to hook up events to tell you process is created and deleted using a ManagementEventWatcher as shown in this blog post http://weblogs.asp.net/whaggard/438006.
WMI gives you a visible performance hit with noticeable recurring CPU spikes when looking at it run in task manager. The way I made my process hunting work was to use a linq statement on Process.GetProcessByName, which I've never seen go above 0% when scanning for processes every .3 seconds. I store the processes I already know about in the memory, and filter them out in the linq statement.
If your EXE has enough permission (or is elevated), you can set EnableRaisingEvents = true, and attach to the Exited event to know exactly when the process dies.
I am writing a program that does one thing, it finds out the current link speed of the wifi connection and reports it to the user in real time. the problem I am having is that it does not seem to be able to find out the current link speed, only the max link speed of the device (300 Mbps). the reason I am writing this is that I have a problem where, periodically the link speed will drop drastically (down to 1-2 Mbps) and I want to be able to see when that happens. with this code it will simply give me the maximum speed that the adapter supports, not the current link speed of the connection.
private void update(object state)
{
System.Net.NetworkInformation.NetworkInterface[] nics = null;
nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
long speed = 0;
string adapter = "";
foreach (System.Net.NetworkInformation.NetworkInterface net in nics)
{
if (net.Name.Contains("Wireless") || net.Name.Contains("WiFi") || net.Name.Contains("802.11") || net.Name.Contains("Wi-Fi"))
{
speed = net.Speed;
adapter = net.Name;
break;
}
}
string temp;
if (speed == 0)
{
temp = "There is currently no Wi-Fi connection";
}
else
{
temp = "Current Wi-Fi Speed: " + (speed / 1000000) + "Mbps on " + adapter;
}
if (label1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(update);
label1.Invoke(d, new object[] { temp });
}
else
{
label1.Text = temp;
}
}
this run by calling
System.Threading.Timer ticker = new System.Threading.Timer(update, label1, 0, 1000);
in the main method.
Considering that it literally took me the whole entire day to find what the solution to this was, I figured I'd at least show StackOverflow for future reference what I came across and what did and did not work for this question.
tl;dr: Scroll to the The Code section
What I found
Good ol' control panel
If you are looking for the really easy way to do this you can simply go and open Contol Panel. Depending on what version of Windows you are on (in my case I'm on Windows 8), the path to the page is Control Panel >> Network and Internet >> Network and Sharing Center and then you can click on the link next to "Connections: " which will give you a window that looks like what is below.
The current link speed is highlighted in red which in my case is 36.0 Mbps. Though, of course, this might not satisfy your original question if you were intending to integrate some code with the actual value.
WMI
With a mix of Googling and whatnot, I thought I might have found something in Windows Management Instrumentation.
Long story short, AFAIK, WMI does not have what we're looking for.
WMI, in short, is a giant object database (that
can also be queried through SQL) that allows you to query information about a
Windows machine such as process, disks, etc. In WMI, everything is
represented by a class with a series of instances each with a set of
properties.
Anyhow, WMI Explorer allows you to view all of this on your machine.
I (supposedly) found two classes on MSDN that might have the info on link speed but from WMI Explorer, there was nothing useful.
The first class, MSFT_NetAdapter, did not even show up in WMI Explorer on my machine.
The second class, Win32_NetworkAdapter, showed up in WMI Explorer, but the Speed property was still incorrect. The same network adapter was showing a value of 168000000 or 168 Mbps which is not right. Though I find this strange because there was already a MaxSpeed but it was blank.
Scratch WMI off the list.
Win32 P/Invoke
Yes, of course, the solution to everything is always calling unmanaged Win32 APIs using P/Invoke magic.
This is the route used to solve the problem.
Luckily, the IP_ADAPTER_ADDRESSES structure solves the problem. If you look at the MSDN page, it's a fairly large structure but what is important here is TransmitLinkSpeed which actually works.
Calling the GetAdaptersAddresses() function will return the actual structure.
Now, the actual C# P/Invoke code. Luckily, pinvoke.net already had interop for this function which I've added. This is all that was necessary.
The Code
Finally, here is your code patched up with the new P/Invoke black magic. I've made it work as a console application for demo purposes:
Using Statements:
using System;
using System.Threading;
Code:
class Program
{
private static void Main(string[] args)
{
Timer ticker = new Timer(Update, null, 0, 1000);
// Keep the main thread from dying
while (true)
{
Thread.Sleep(1000);
}
}
private static void Update(object state)
{
ulong speed = 0;
string adapter = "";
string[] nameSearches = { "Wireless", "WiFi", "802.11", "Wi-Fi" };
// The enum value of `AF_INET` will select only IPv4 adapters.
// You can change this to `AF_INET6` for IPv6 likewise
// And `AF_UNSPEC` for either one
foreach (IPIntertop.IP_ADAPTER_ADDRESSES net in IPIntertop.GetIPAdapters(IPIntertop.FAMILY.AF_INET))
{
bool containsName = false;
foreach (string name in nameSearches)
{
if (net.FriendlyName.Contains(name))
{
containsName = true;
}
}
if (!containsName) continue;
speed = net.TrasmitLinkSpeed;
adapter = net.FriendlyName;
break;
}
string temp;
if (speed == 0)
{
temp = "There is currently no Wi-Fi connection";
}
else
{
temp = string.Format("Current Wi-Fi Speed: {0} Mbps on {1}", (speed / 1000000.0), adapter);
}
Console.WriteLine(temp);
}
}
You are then going to be looking for the actual IPIntertop class that I updated. Since it's pretty big you can find it updated at pinvoke.net or on this PasteBin in case something goes down.
Bottom Line
Windows has a lot of APIs which are somewhat broken (WMI), can have a few "leaky abstractions" (.Net), or can be a pain to work with (Win32).
Sigh, that is a lot and I hope it helps.
I come accross the same issue, and need to get windows wifi link speed which is current negotiated.
and thanks to #Jaxrtech's WMI approach, that really works.
the correct class is CIM_NetworkAdapter(i'm using windows7), and query the speed column to get the current speed.
while wifi current negotiated speed is changing, this speed is changing too. i tested it, this matched ok.
select Description , DeviceID, Speed from CIM_NetworkAdapter
get:
D-Link DWA-140 RangeBooster N USB Adapter 17 285000000
Since no-one here mentioned it yet: why not use https://learn.microsoft.com/en-us/dotnet/api/system.net.networkinformation.networkinterface.speed?view=net-5.0#System_Net_NetworkInformation_NetworkInterface_Speed
This is, if the table on this site is correct included since .NET Framework 2.0 and seem to included in all other versions of .net including .net core.
Ok, little bit of background here. I have a large scale web application (MVC3) which does all kinds of unimportant stuff. I need this web application to have the ability to schedule ad-hoc Quartz.NET jobs in an Oracle database. Then, I want the jobs to be executed later on via a windows service. Ideally, I'd like to schedule them to run in even intervals, but with the option to add jobs via the web app.
Basically, the desired architecture is some variation of this:
Web app <--> Quartz.NET <--> Database <--> Quartz.NET <--> Windows Service
What I have coded up so far:
A windows service which (for now) schedules AND runs the Jobs. This obviously isn't going to be the case in the long run, but I'm wondering if I can keep just this and modify it to have it basically represent both "Quartz.NET's" in the diagram above.
The web app (details I guess aren't very important here)
The jobs (which are actually just another windows service)
And a couple important notes:
It HAS to be run from a windows service, and it HAS to be scheduled through the web app (to reduce load on IIS)
The architecture above can be rearranged a little bit, assuming the above bullet still applies.
Now, a few questions:
Is this even possible?
Assuming (1) passes, what do you guys think is the best architecture for this? See first bullet on what I've coded up.
Can somebody maybe give me a few Quartz methods that will help me out with querying the DB for jobs to execute once they're already scheduled?
There will be a bounty on this question in as soon as it is eligible. If the question is answered in a satisfactory way before then, I will still award the bounty to the poster of the answer. So, in any case, if you give a good answer here, you'll get a bounty.
I'll try answering your questions in the order you have them.
Yes, it's possible to do this. It's actually a common way of working with Quartz.Net. In fact, you can also write an ASP.Net MVC application that manages Quartz.Net schedulers.
Architecture. Ideally and at a high level, your MVC application will use the Quartz.Net API to talk to a Quartz.Net server that is installed as a windows service somewhere. Quartz.Net uses remoting to communicate remotely, so any limitations of using remoting apply (like it's not supported in Silverlight, etc). Quartz.Net provides a way to install it as a windows service out of the box, so there really isn't much work to be done here, other than configuring the service itself to use (in your case) an AdoJobStore, and also enabling remoting. There is some care to be taken around how to install the service properly, so if you haven't done that yet, take a look at this post.
Internally, in your MVC application you'll want to get a reference to the scheduler and store it as a singleton. Then in your code you'll schedule jobs and get information about the scheduler through this unique instance. You could use something like this:
public class QuartzScheduler
{
public QuartzScheduler(string server, int port, string scheduler)
{
Address = string.Format("tcp://{0}:{1}/{2}", server, port, scheduler);
_schedulerFactory = new StdSchedulerFactory(getProperties(Address));
try
{
_scheduler = _schedulerFactory.GetScheduler();
}
catch (SchedulerException)
{
MessageBox.Show("Unable to connect to the specified server", "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
public string Address { get; private set; }
private NameValueCollection getProperties(string address)
{
NameValueCollection properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "RemoteClient";
properties["quartz.scheduler.proxy"] = "true";
properties["quartz.threadPool.threadCount"] = "0";
properties["quartz.scheduler.proxy.address"] = address;
return properties;
}
public IScheduler GetScheduler()
{
return _scheduler;
}
}
This code sets up your Quart.Net client. Then to access the remote scheduler, just call
GetScheduler()
Querying
Here is some sample code to get all the jobs from the scheduler:
public DataTable GetJobs()
{
DataTable table = new DataTable();
table.Columns.Add("GroupName");
table.Columns.Add("JobName");
table.Columns.Add("JobDescription");
table.Columns.Add("TriggerName");
table.Columns.Add("TriggerGroupName");
table.Columns.Add("TriggerType");
table.Columns.Add("TriggerState");
table.Columns.Add("NextFireTime");
table.Columns.Add("PreviousFireTime");
var jobGroups = GetScheduler().GetJobGroupNames();
foreach (string group in jobGroups)
{
var groupMatcher = GroupMatcher<JobKey>.GroupContains(group);
var jobKeys = GetScheduler().GetJobKeys(groupMatcher);
foreach (var jobKey in jobKeys)
{
var detail = GetScheduler().GetJobDetail(jobKey);
var triggers = GetScheduler().GetTriggersOfJob(jobKey);
foreach (ITrigger trigger in triggers)
{
DataRow row = table.NewRow();
row["GroupName"] = group;
row["JobName"] = jobKey.Name;
row["JobDescription"] = detail.Description;
row["TriggerName"] = trigger.Key.Name;
row["TriggerGroupName"] = trigger.Key.Group;
row["TriggerType"] = trigger.GetType().Name;
row["TriggerState"] = GetScheduler().GetTriggerState(trigger.Key);
DateTimeOffset? nextFireTime = trigger.GetNextFireTimeUtc();
if (nextFireTime.HasValue)
{
row["NextFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime(nextFireTime.Value.DateTime);
}
DateTimeOffset? previousFireTime = trigger.GetPreviousFireTimeUtc();
if (previousFireTime.HasValue)
{
row["PreviousFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime(previousFireTime.Value.DateTime);
}
table.Rows.Add(row);
}
}
}
return table;
}
You can view this code on Github
I need some advice regarding an application I wrote. The issues I am having are due to my DAL and connections to my SQL Server 2008 database not being closed, however I have looked at my code and each connection is always being closed.
The application is a multithreaded application that retrieves a set of records and while it processes a record it updates information about it.
Here is the flow:
The administrator has the ability to set the number of threads to run and how many records per thread to pull.
Here is the code that runs after they click start:
Adapters are abstractions to my DAL here is a sample of what they look like:
public class UserDetailsAdapter: IDataAdapter<UserDetails>
{
private IUserDetailFactory _factory;
public UserDetailsAdapter()
{
_factory = new CampaignFactory();
}
public UserDetails FindById(int id){
return _factory.FindById(id);
}
}
As soon as the _factory is called it processes the SQL and immediately closes the connection.
Code For Threaded App:
private int _recordsPerthread;
private int _threadCount;
public void RunDetails()
{
//create an adapter instance that is an abstration
//of the data factory layer
var adapter = new UserDetailsAdapter();
for (var i = 1; i <= _threadCount; i++)
{
//This adater makes a call tot he databse to pull X amount of records and
//set a lock filed so the next set of records that are pulled are differnt.
var details = adapter.FindTopDetailsInQueue(_recordsPerthread);
if (details != null)
{
var parameters = new ArrayList {i, details};
ThreadPool.QueueUserWorkItem(ThreadWorker, parameters);
}
else
{
break;
}
}
}
private void ThreadWorker(object parametersList)
{
var parms = (ArrayList) parametersList;
var threadCount = (int) parms[0];
var details = (List<UserDetails>) parms[1];
var adapter = new DetailsAdapter();
//we keep running until there are no records left inthe Database
while (!_noRecordsInPool)
{
foreach (var detail in details)
{
var userAdapter = new UserAdapter();
var domainAdapter = new DomainAdapter();
var user = userAdapter.FindById(detail.UserId);
var domain = domainAdapter.FindById(detail.DomainId);
//...do some work here......
adapter.Update(detail);
}
if (!_noRecordsInPool)
{
details = adapter.FindTopDetailsInQueue(_recordsPerthread);
if (details == null || details.Count <= 0)
{
_noRecordsInPool = true;
break;
}
}
}
}
The app crashes because there seem to be connection issues to the database. Looking in my log files for the DAL I am seeing this:
Timeout expired. The timeout period
elapsed prior to obtaining a
connection from the pool. This may
have occurred because all pooled
connections were in use and max pool
size was reached
When I run this in one thread it works fine. I am guessing when I runt his in multiple threads I am obviously making too many connections to the DB. Any thoughts on how I can keep this running in multiple threads and make sure the database doesn’t give me any errors.
Update:
I am thinking my issues may be deadlocks in my database. Here is the code in SQL that is running whe I get a deadlock error:
WITH cte AS (
SELECT TOP (#topCount) *
FROM
dbo.UserDetails WITH (READPAST)
WHERE
dbo.UserDetails where IsLocked = 0)
UPDATE cte
SET
IsLocked = 1
OUTPUT INSERTED.*;
I have never had issues with this code before (in other applications). I reorganzied my Indexes as they were 99% fragmented. That didn't help. I am at a loss here.
I'm confused as to where in your code connections get opened, but you probably want your data adapters to implement IDispose (making sure to close the pool connection as you leave using scope) and wrap your code in using blocks:
using (adapter = new UserDetailsAdapter())
{
for (var i = 1; i <= _threadCount; i++)
{
[..]
}
} // adapter leaves scope here; connection is implicitly marked as no longer necessary
ADO.NET uses connection pooling, so there's no need to (and it can be counter-productive to) explicitly open and close connections.
It is not clear to me how you actually connect to the database. The adapter must reference a connection.
How do you actually initialize that connection?
If you use a new adapter for each thread, you must use a new connection for each adapter.
I am not too familiar with your environment, but I am certain that you really need a lot of open connections before your DB starts complaining about it!
Well, after doing some research I found that there might be a bug in SQL server 2008 and running parallel queries. I’ll have to dig up the link where I found the discussion on this, but I ended up running this on my server:
sp_configure 'max degree of parallelism', 1;
GO
RECONFIGURE WITH OVERRIDE;
GO
This can decrease your server performance, overall, so it may not be an option for some people, but it worked great for me.
For some queries I added the MAXDOP(n) (n being the number of processors to utilize) option so they can run more efficiently. It did help a bit.
Secondly, I found out that my DAL’s Dispose method was using the GC.Suppressfinalize method. So, my finally sections were not firing in my DAL properly and not closing out my connections.
Thanks to all who gave their input!