|
This is NOT a programming question. I just figured that since a few of you are programmers, you might be interested in what I'm doing.
I made a preliminary test run of my Sql Express Agent Service code. This is exercising the Timer agents (agents that run at a specified interval (or on a certain day/date). Multiple agent tasks can be implemented via app.config entries. The intervals for the three tasks represented below are set at 1 minute (Interval Task 01), two minutes (Interval Task 2), and 3 minutes (Interval Task 03).
12:11 AgentTimerTest01 - started module
12:11 Interval Task 01 - Tick
12:11 Interval Task 02 - Tick
12:11 Interval Task 03 - Tick
The thread 0x14edc has exited with code 259 (0x103).
12:12 Interval Task 01 - Tick
The thread 0x1564c has exited with code 259 (0x103).
12:13 Interval Task 01 - Tick
12:13 Interval Task 02 - Tick
The thread 0x14ea8 has exited with code 259 (0x103).
12:14 Interval Task 01 - Tick
12:14 Interval Task 03 - Tick
The thread 0x15768 has exited with code 259 (0x103).
12:15 Interval Task 01 - Tick
12:15 Interval Task 02 - Tick
The thread 0x157e0 has exited with code 259 (0x103).
12:16 Interval Task 01 - Tick
The thread 0x15518 has exited with code 0 (0x0).
The thread 0x15704 has exited with code 259 (0x103).
The thread 0x28b0 has exited with code 259 (0x103).
12:17 Interval Task 01 - Tick
12:17 Interval Task 02 - Tick
12:17 Interval Task 03 - Tick
Each add-in module will be hot pluggable, and will be reconfigurable via its config file, as well as reconfigurable tasks - while the service is running. Currently there are three supported agent classes:
Timer - time-based agents (uses my Schedule Future Dates article)
FileSystem - watches the specified folder for the specified file mask (uses my FileWatcherEx article)
WebRequest - derived from the Timer agent, and performs a web request on the configured URL at the specified time/date interval
One or more of each type of agent can be configured for each plug-in module.
I've restarted this project from scratch five times so far, and I think I've finally got a solid start. The absolute biggest hurdle has been abstracting behavior to lessen the amount of work that's required to write for new modules.
Here's the "do work" code:
protected void DoWork(AgentTask taskObj)
{
this.DoAgentWork();
DateTime targetTime = DateTime.Now;
do
{
targetTime = targetTime.GetFutureDateTime(this.Config.Schedule, this.Config.TimeOfDay, this.Config.DayOfWeek, this.Config.Ordinal, this.Config.Month);
CancellationTokenSource tokenSource = new CancellationTokenSource(targetTime - DateTime.Now);
Task waiter = new Task(() =>
{
SpinWait.SpinUntil( () => tokenSource.IsCancellationRequested || taskObj.CancelToken.IsCancellationRequested);
}, tokenSource.Token);
waiter.Start();
waiter.Wait();
if (!taskObj.CancelToken.IsCancellationRequested)
{
this.DoAgentWork();
}
} while (!taskObj.CancelToken.IsCancellationRequested);
}
private void DoAgentWork()
{
Debug.WriteLine("{0} {1} - Tick", DateTime.Now.ToString("hh:mm"), this.Config.Name);
}
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
modified 3-Mar-15 14:06pm.
|
|
|
|
|
Epic fail. No fart jokes or pictures of naked elephants.
Seriously, put this is your blog or something and keep us updated. I love this kind of stuff.
|
|
|
|
|
Slacker007 wrote: naked elephants. Uh, this is the Lounge. Take it to the soapbox.
There are only 10 types of people in the world, those who understand binary and those who don't.
|
|
|
|
|
eh, don't be a sunshine.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein
|
|
|
|
|
TheGreatAndPowerfulOz wrote: don't be a sunshine. Why don't you put your comment where the sun don't shine.
There are only 10 types of people in the world, those who understand binary and those who don't.
|
|
|
|
|
Well, elephant that why don't you?
If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein
|
|
|
|
|
John Simmons / outlaw programmer wrote:
this.DoAgentWork();
do
{
this.DoAgentWork();
if (!taskObj.CancelToken.IsCancellationRequested)
{
this.DoAgentWork();
}
} while (!taskObj.CancelToken.IsCancellationRequested); Is, IMHO, better. Removed <snip>'d code for clarity.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein
|
|
|
|
|
Actually, this would be even better:
this.DoAgentWork(taskObj.CancelToken);
(and I already made a not in my code to do that).
That way a long-running process inside DoAgentWork could watch the status of the token.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein
|
|
|
|
|
This bit looks wrong to me:
Task waiter = new Task(() =>
{
SpinWait.SpinUntil( () => tokenSource.IsCancellationRequested || taskObj.CancelToken.IsCancellationRequested);
}, tokenSource.Token);
waiter.Start();
waiter.Wait();
You're starting a task on a background thread which blocks until either the AgentTask is cancelled or the target time is reached, but then you're blocking the current thread waiting for that task to complete.
I suspect there's a better way of doing it - but this isn't the right forum to discuss it.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
The waiter has a cancellation token and waits until either the timeout or a cancelation token is activated. Beyond that, the thread needs to wait until the waiter is done before continuing, and it doesn't block any other running agent tasks. I don't understand how that's incorrect.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
You're pushing work off onto a background thread, and then blocking the current thread waiting for the work to finish. You could almost certainly move the work out onto the current thread without changing the behaviour:
Task waiter = new Task(() =>
{
SpinWait.SpinUntil( () => tokenSource.IsCancellationRequested || taskObj.CancelToken.IsCancellationRequested);
}, tokenSource.Token);
waiter.Start();
waiter.Wait();
SpinWait.SpinUntil( () => tokenSource.IsCancellationRequested || taskObj.CancelToken.IsCancellationRequested);
There might be a way to make it work without blocking the current thread, using async / await .
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
But I WANT to block the thread (and it's even still responsiove to the cancel token). It's simply waiting for a time span to go by before doing the work at the bottom of the loop.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Yes, you want to block the current thread; but your code is blocking TWO threads!
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Good point.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein
|
|
|
|
|
Doing it your way makes it run forever. I still need it to cancel itself after the timeout has expired.
I think I see what you're saying - gotta run it that way to see what it does.
Real work is yanking on my sleeve, so I have to pick this up in an hour or two.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
John Simmons / outlaw programmer wrote: Sql Express Agent
Get a couple certificates and now you are an expert!
Mongo: Mongo only pawn... in game of life.
|
|
|
|
|
|
Add "Undo Pending Changes" to the code window tab's context menu.
Now I won't have to search all over the solution to find the file because I accidentally hit the keyboard.
If it's not broken, fix it until it is
|
|
|
|
|
In 2012 + there's a button at the top of the solution explorer with two arrows:
->
<-
That will highlight the current open document in solution explorer. Use it many times a day myself.
|
|
|
|
|
|
I know. I really meant is as a bitch
If it's not broken, fix it until it is
|
|
|
|
|
|
ctrl-z
If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein
|
|
|
|
|
Mine's "Just work".
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|