I would like to run every x second script that uses apoc.periodic.commit. The natural way for me would be to put it inside apoc.periodic.repeat.
But: If I do something like this:
CALL apoc.periodic.repeat(
"test",
"
CALL apoc.periodic.commit(
'
CREATE (a:TEST)
WITH a LIMIT 1
RETURN 0;
'
)
",
1
);
the Neo4j start executing it,... but never finish (It doesn't insert Node TEST). And if I stop the periodic and registrate a new one (one without apoc.periodic.commit, that I know works), the new one doesn't run either... I need to restart the Neo4j to work again.
Any suggestion on where I am doing wrong?
Related
I have a script in LINQPad that looks like this:
var serverMode = EnvironmentType.EWPROD;
var jobToSchedule = JobType.ABC;
var hangfireCs = GetConnectionString(serverMode);
JobStorage.Current = new SqlServerStorage(hangfireCs);
Action<string, string, XElement> createOrReplaceJob =
(jobName, cronExpression, inputPackage) =>
{
RecurringJob.RemoveIfExists(jobName);
RecurringJob.AddOrUpdate(
jobName,
() => new BTR.Evolution.Hangfire.Schedulers.JobInvoker().Invoke(
jobName,
inputPackage,
null,
JobCancellationToken.Null),
cronExpression, TimeZoneInfo.Local);
};
// psuedo code to prepare inputPackage for client ABC...
createOrReplaceJob("ABC.CustomReport.SurveyResults", "0 2 * * *", inputPackage);
JobStorage.Current.GetConnection().GetRecurringJobs().Where( j => j.Id.StartsWith( jobToSchedule.ToString() ) ).Dump( "Scheduled Jobs" );
I have to schedule in both QA and PROD. To do that, I toggle the serverMode variable and run it once for EWPROD and once for EWQA. This all worked fine until recently, and I don't know exactly when it changed unfortunately because I don't always have to run in both environments.
I did purchase/install LINQPad 7 two days ago to look at some C# 10 features and I'm not sure if that affected it.
But here is the problem/flow:
Run it for EWQA and everything works.
Run it for EWPROD and the script (Hangfire components) seem to run in a mix of QA and PROD.
When I'm running it the 'second time' in EWPROD I've confirmed:
The hangfireCs (connection string) is right (pointing to PROD) and it is assigned to JobStorage.Current
The query at the end of the script, JobStorage.Current.GetConnection().GetRecurringJobs() uses the right connection.
The RecurringJob.* methods inside the createOrReplaceJob Action use the connection from the previous run (i.e. EWQA). If I monitor my QA Hangfire db, I see the job removed and added.
Temporary workaround:
Run it for EWQA and everything works.
Restart LINQPad or use 'Cancel and Reset All Queries' method
Run it for EWPROD and now everything works.
So I'm at a loss of where the issue might lie. I feel like my upgrade/install of LINQPad7 might be causing problems, but I'm not sure if there is a different way to make the RecurringJob.* static methods use the 'updated' connection string.
Any ideas on why the restart or reset is now needed?
LINQPad - 5.44.02
Hangfire.Core - 1.7.17
Hangfire.SqlServer - 1.7.17
This is caused by your script (or a library that you call) caching something statically, and not cleaning up between executions.
Either clear/dispose objects when you're done (e.g., JobStorage.Current?) or tell LINQPad not to re-use the process between executions, by adding Util.NewProcess=true; to your script.
I ran into an issue where I had long running JitterBit operations that were scheduled. I had them scheduled close together, since I needed to keep data flowing. But, when they would take longer than expected I would wind up with multiple instances of the operation set running at the same time. This was killing my performance.
I'll put the fix in the answer below.
To resolve this issue I added an additional Script Operation at the beginning of my operation set (with the schedule running on this operation). This script simply checks to see if one of the operations in this set is already running. If not, it starts the next operation. If there is anything running, it exists and waits till the next scheduled instance.
This is a sample of my script. This one assumes that there were originally two operations in this operation set.
<trans>
$isInQueue=GetOperationQueue("<TAG>Operations/OperationToCheck01</TAG>");
$isInQueue2=GetOperationQueue("<TAG>Operations/OperationToCheck02</TAG>");
$isRunning=$isInQueue[0][1];
$isRunning2=$isInQueue2[0][1];
if(($isRunning==1 && $isRunning!=Null()) || ($isRunning2==1 && $isRunning2!=Null()),
WriteToOperationLog("Skip for now: "+$isRunning+" / "+$isRunning2);,
WriteToOperationLog("Nothign is Running - Starting Operation Chain.");
RunOperation("<TAG>Operations/OperationToCheck01</TAG>");
);
</trans>
In normal applescript, the script is executed down the page, and so any code in loops for every 5 seconds will only run while the loop is running - there is no way to have a single function run every few second regardless of what the script is currently doing or where it is in the script (that I know of). In cocoa-applescript, however, is there a way to run a handler every 5 seconds, at all times, no matter what it is currently doing? Here is what it should be doing in my cocoa-applescript app:
on checkInternetStrength()
do shell script "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep 'agrCtlRSSI:'" -- this being the script which returns the line containing the signal strength
set SignalStrength to result
set RSSIcount to (count of characters in SignalStrength)
set SignalStrength to ((characters 18 thru RSSIcount of SignalStrength) as string) as integer -- this to turn SignalStrength into just the number and not the whole output line
set SignalStrength to (100 + SignalStrength) as integer
set SignalBar's setIntValue_(SignalStrength) -- SignalBar being the Level Indicator described below
end checkInternetStrength
Summed up, it runs the airport command to check internet connection, turns this into a number from 1 to 100 and uses this on an NSLevelIndicator (100 maximum) to show current signal strength graphically. Now, there is no point having this run once or when you hit a button - that is an option, but it would be nice if it updated itself every, say, 5 seconds with the realtime value. So is there any way to have a process which runs every 5 seconds to do this, while still enabling full functionality of the rest of the script and interface - i.e. as a background process? Comment if you need more extracts from the script.
Example
In Unity-C# scripting, the 'void Update() {code}' will run the code within it every frame while doing everything else simultaneously, so a cocoa-applescript version of this might be an answer, if anyone knows.
I Dont believe this is possible but what I had a similar problem before, what i do, I have an external applescript applicaion that is hidden the repeats the commands, the only problem is, it wont send it back to the app, you'll have to make the external applescript app do it, like
display notification, etc..., in the applescript apps "Info.plist" you can add this:
<key>LSUIElement</key>
<string>1</string>
To make the app run invisibly, but sorry i dont think you can run a handler in the app its self
I have this code:
If CheckBox1.Checked = True Then
My.Computer.FileSystem.RenameFile("C:\Users\mario\Desktop\Dominio\1\Pc - S.txt", "Pc - S - A.txt")
'Sleep(2000) ' to sleep for 2 second
System.Threading.Thread.Sleep(2000)
My.Computer.FileSystem.RenameFile("C:\Users\mario\Desktop\Dominio\1\Pc - S - A.txt", "Pc - S.txt")
End If
If CheckBox2.Checked = True Then
My.Computer.FileSystem.RenameFile("C:\Users\mario\Desktop\Dominio\2\Pc - S.txt", "Pc - S - A.txt")
'Sleep(2000) ' to sleep for 2 second
My.Computer.FileSystem.RenameFile("C:\Users\mario\Desktop\Dominio\2\Pc - S - A.txt", "Pc - S.txt")
End If
And it continues with another 24 if's. I need them to change the name all at the same time and then wait two seconds and change it again all at the same time.Will i need to have 48(24+24) IF's?
Explanation:
Im creating a super simple way of shuting down the computers at my school. Here is my idea(hope you can understand it)
I put a program at every computer at school (in the regestry at the startup) that does the following:
(Atencion not really in a programing language)
for(1){
sleep 1000 // wait 1 sec
if.FILE.EXISTS(\\domain\folder1\shutdown.txt) then{
do: shutdown pc // if file exist it shutdowns the pc
}
}
So what this does is if there is a file in a certain directory in the domain, it shutsdown the pc.
Im doing this for 24 pcs, so i need to shutdown them individualy, therefor the many folders.
So i could simply rename the files by hand, but for 24 pcs that is a lot of work. So im developing a aplication that asks me what pcs i want to shutdown and then does:
1: Rename file.
2: Wait 2 or more seconds (so the computers in the network have time to verify if there is such file)
3: rename back the file so when the pc restarts it doesnt shutdown again.
Did you get what im trying to do? And yes there are more orthodox ways of doing this. but this is really simple, and this is more of a test than anything. (Later will be using more proper ways of doing this and do other options over the network)
Since the only difference is a single number in the filepath, why not do something like this?
var dict = new Dictionary<CheckBox, string>();
dict.Add(CheckBox1, "1");
dict.Add(CheckBox2, "2");
//etc
foreach (var kvp in dict)
{
if(kvp.Key.Checked == true)
{
My.Computer.FileSystem.RenameFile(String.Format("C:\Users\mario\Desktop\Dominio\{0}\Pc - S.txt", kvp.Value ), "Pc - S - A.txt")
}
}
We create a generic dictionary to store the association of the checkboxes to the string/number and then loop through the dictionary, checking the values. We use a format string (you could use string concatenation instead) to insert the string/number into the filepath string.
Note, this is in C#, as I'm not a VB programmer. The syntax will likely be slightly different.
Since your intention is to remotely shut down the PC's, why not actually shut them down from your code, rather than some hackish "create files then wait 2 seconds" approach?
Again, this is C# but the translation should be pretty straightforward:
var ComputerNames = new List<string>() {"Computer1", "Computer2", "Computer3"};
foreach(var pc in ComputerNames)
{
Process.Start("shutdown","-s -m \\\\" + pc);
}
I am using server push in Wt and I am trying to push a new chart with the following code:
Wt::WApplication::UpdateLock uiLock(app);
if (uiLock){
chart_ste = new ScatterPlotExample(this,10*asf.get_outputSamplingRate());
app->triggerUpdate();
}
but it waits for the program to end and then it prints it whereas the following code in the same program pushes the word "Demokritus every 0.5 secs as it should do:
for (int i=0; i<10; i++)
{
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
Wt::WApplication::UpdateLock uiLock(app);
if (uiLock) {
showFileName = new WText(this);
showFileName->setText(boost::lexical_cast<std::string>("Demokritus"));
app->triggerUpdate();
}
}
What might be my mistake?
The documentation for triggerUpdate mentions that "The update is not immediate, and thus changes that happen after this call will equally be pushed to the client." If the changes are not immediate, it could be that the first piece of code continuously tries to push updates as fast as your CPU will allow it, so it never gets to the server because a new update overwrites the last and it begins waiting again. Try adding boost::this_thread::sleep(boost::posix_time::milliseconds(500)); to the first piece of code to see if that helps.
I've done a project once where I needed to update a chart every second with new data and had a very similar setup to yours. I put in the sleep from the start because I did not want my boost thread to use too much CPU.
Also, it is unclear if the first piece of code is in a bigger loop, if it is, you probably shouldn't make a new chart every time, but create it before hand and then update it with data. I hope some of this helps.