AutoHotkey Community

It is currently May 26th, 2012, 9:15 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: May 20th, 2009, 8:44 am 
Quick question for everyone about how the priority works (for the entire script via process, priority...), probably a windows question really, but maybe someone knows off the top of your head

situation:
-single instance is off
-each called instance does a FileAppend to a .log file (%0%is>0), then exits

problem:
calling the script too fast causes out of order logs...

what i think is happening is the new instance is suspending the first instance, logging, exiting, and then the first instance can finish logging

best way to solve this?
I could detect other instances running, and if there are, sleep, or lower the priority, (will doing so immediately cause a higher priority process to take control)

any help appreciated, i can post code if necessary but its really a more general question

- gwarble
www.arcadefanatic.com


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: May 20th, 2009, 2:20 pm 
Offline

Joined: October 7th, 2006, 4:50 pm
Posts: 3157
Location: MN, USA
I don't think process priority will effectively solve this problem (but in my opinion, process priority doesn't solve any AHK problems). It sounds like you'd be better off using SingleInstance, Ignore to prevent conflict between multiple instances, and each instance should trigger the next only after it's finished. You could also use Sleep, as you noted, if the timing isn't important.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 22nd, 2009, 9:52 am 
thanks for your help

unfortunately, each instance is not triggering the next instance, but instead one script is being called by an external program with command line parameters when a certain condition is met (CNC machines, using a DNC server, which calls my script upon status changes (for machine tracking/monitoring/status reporting/etc...) if you want specific info, lmk)

so i can't control when one call to the script happens in relation to another call... that would defeat the purpose... the entirety of the process is short, less than a second or so, so the problem only arises if a machine changes statuses two times sequentially without delay (ie if the script is run with parameter "start" and then immediately the script is run again with parameter "end", or in the real shop the machine runs a program, with fanuc's custom macro B: "DPRNT [ ///*START ], that command is read by DNC Server, upon which it executes "script.ahk start" or "script.ahk end" respectively... so a CNC program like this:
%
O99 ( TEST )
DPRNT [ ///*START ]
blah blah blah
DPRNT [ ///*END ]
M30
%

with "blah blah blah" missing (or blah being something on the machine which processes fast and doesn't move axis or anything)

ok i'm starting to not be able to understand myself so this probably doesn't make sense, but its late and i'll explain better tomorrow

- gwarble


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: May 22nd, 2009, 10:35 am 
Quote:
ok i'm starting to not be able to understand myself
Don't be afraid. Someone told me that women have to deal with that scenario by default :lol:

a) Why not create separate Logs?
Code:
Run, myLogger.ahk /PushingBox:10

MyLogger.ahk
Code:
Process := SubStr(%1%,16,-1)
FileAppend, % A_Now "`t" Process "`tmy super duper process status here`n", %Process%.log


b) D'ya need to merge that logging into a single file? Why not use a Timer to parse the seperate logs to merge their content into the single log (a simple sort for lines which are tagged via the TimeStamp should fit, right)?

But I might have lost you ... :(


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: May 23rd, 2009, 5:32 am 
Offline

Joined: May 23rd, 2009, 4:48 am
Posts: 361
Location: north bay, california
hey man
thanks for the input...

so to explain better, and to keep in mind one goal is to keep this as a single distributable exe, here is what really happens, from the user perspective

the exe can be run normally, giving multiple gui interfaces allowing manual machine status change via context menu. this exe polls an ini file for changes, and when updated, reads the appropriate machine's log file reading current status, and history of previous logs [wherein lies the problem when they are out of order] Manually changing the status via gui doesn't really change the internal status of that machine, but rather logs the change and updates said ini file, the same as the following use...

the exe can also be run with command line parameters, which updates the ini, logs to the machine's daily log, and logs to the general scripts monthly log (designed to be called by another program, a DNC server for serial comm. to the cnc machines). I realize it would have been simpler to make a separate script to handle the direct logging calls, but its been a fun challenge getting it working as well as it is... so when the command line parameters are used, that instance logs and then exits... when none are used it just detects and kills the other running instances (since singleinstance couldnt be used for the above functionality req) and then restarts (acts like singleinstance force when an icon is run from windows, but acts like single instance off when called with command line parameters)

to make it slightly more complicated (and to explain why its functioning the way it does by updating files and polling those files, instead of just storing the pertinant info in memory... but the reason is this. besides the 1 persistant instance running all the time, and the other superquick instances running from command line calls, and other superquick instances running from hotkeys (wired to machine's relays).......
there are a few pcs on the network, doing the same thing (except to that remote ini and log file on the server)... mostly reading but with the ability to update statuses...

i shuold be using the tcp/ip functionality well documented on these forums at some point but i havent tackled that one yet... and it will cause other problems with functionality...

got long winded again, i'll end there, i'm gonna tidy up some code tonight and see if i feel like posting it all on here... if anyone is interested (otherwise i'll wait til its better and post a new thread to scripts instead...)

here's the code that's doing whats pertinant to this convo:
Code:
#SingleInstance Off  ;Force
#Persistent
#NoTrayIcon
#NoEnv
SetWorkingDir, %A_ScriptDir%
DetectHiddenWindows, On
OnExit, ExitMyScript
 If %1%
  GoSub, SMServer
 WinGet, InstanceID, List, %A_ScriptFullPath%
 Loop %InstanceID%
  If A_Index <> 1
   SendMessage, 0x1111, 1, 65134, , % "ahk_id " InstanceID%A_Index%
 OnMessage(0x1111, "AnotherInstance")
 GoSub, Initialize
Return

CheckForUpdate:
 FileGetTime, UpdateTime, %RemoteIni%
 If LastUpdateTime <> % UpdateTime
  GoSub, UpdatedRemoteIni
 Else
  GoSub, RefreshGUIs
Return

UpdatedRemoteIni:
 Loop %Machine0%
  IniRead, MachineStatus%A_Index%, %RemoteIni%, MachineStatus, % Machine%A_Index%, % MachineStatus%A_Index%
 Loop %Machine0%
  If MachineStatus%A_Index% <> % MachineLastStatus%A_Index%
   GoSub, UpdateFound
 If Details
  Loop %Machine0%
   If MachineStatusChanged%A_Index%
   {
    MachineStatusChanged%A_Index% := False
    RefreshDetails(A_Index)
   }
 If UpdateHTML
  SetTimer, UpdateWWW, -5000
 If LastUpdateTime <> % UpdateTime
  SetTimer, UpdatedRemoteIni, % - RefreshTime * 2000
 LastUpdateTime := UpdateTime
Return


Code:
SMServer:
 SetWorkingDir, %A_ScriptDir%
 RemoteIni = %A_ScriptDir%\MyScript.ini
 LogPath = %A_ScriptDir%
 CommandLine = %1% %2% %3% %4% %5%
 StringUpper, CommandLine, CommandLine, T
 StringSplit, CL, CommandLine, %A_Space%
 StatusList = Start,End,Off,Warm,Alert,Hold,On,Job
 If CL2 in %StatusList%
  GoSub, Update
 Else
  If CL1
   GoSub, FileList
ExitApp

Update:
 SplitPath, RemoteIni, , LogPath
 IfNotExist, %LogPath%\Log\
 {
  FileCreateDir, %LogPath%\Log
  FileCreateDir, %LogPath%\Log\Archive
 }
 FormatTime, NowDate, %A_Now%, yyMMdd
  FileAppend, %A_Now%%A_Tab%%CL1%%A_Tab%%CL2%%A_Tab%%CL3%%A_Tab%%CL4%`n, %LogPath%\Log\%CL1% - %NowDate%.log
 IniWrite, %CL2%, %RemoteIni%, MachineStatus, %CL1%
 FormatTime, NowMonth, %A_Now%, MMMM yyy
 FileAppend, %A_Now%%A_Tab%%CL1%%A_Tab%%CL2%%A_Tab%%CL3%%A_Tab%%CL4%`n, %LogPath%\Log\MyScript - %NowMonth%.log
 If % CL2 = "Job"
  IniWrite, %CL3%, MyScript.ini, MachineJob, %CL1%
 Else
  If % CL3 = "Email"
   GoSub, SendEmail
Return


and also, i'm not sure how multiple log files would solve it, as the timestamp is only by second (A_Now) and the problem really only appears when the two instances are run immediately one after the other, usually under the 1 second resolution of the log data... now because these times are so short, you would think what difference does it make?... but if the machine sends:
START [n seconds] HOLD [n seconds] START [n seconds] END
the log sequence follows START HOLD START END
but if the machine sends:
START [m seconds] HOLD [0 seconds] START [n seconds] END
(notice the 0 seconds) then the log sequence could end up like this:
START (computes to m seconds)
START ( " 0 seconds)
HOLD ( " n seconds)
END
when it might be important to know that the HOLD status was 0 seconds long and that the START status (ie when the machines are running) was N seconds long... when the computation is taken one status to the next in sequence from the log file

thanks
- joel


Report this post
Top
 Profile  
Reply with quote  
PostPosted: July 27th, 2009, 1:54 am 
Offline

Joined: May 17th, 2008, 5:00 am
Posts: 39
Location: Dallas, TX
gwarble wrote:
any help appreciated, i can post code if necessary but its really a more general question
Ok, here goes with the general explanation, I hope this helps:

Your fundamental issue is one of having a central server store what are essentially database updates in serial order when there incoming "packets" are actually out of order due to varying latency. Oh, and the OS of the clients is what is causing the latency.

1) Easiest solution is to instead of sending just "START", send a skosh more information, e.g. "START1", "HOLD2", "START3", "END4". You can then use semantics to properly re-order the data.

2) Use SendMessage() / OnMessage to do a cheap form of IPC. If your verb list is short enough, you can just enumerate them & send the "verb" in wParam, and ticks() in lParam. "But I only want one program" -- no problem. Put both the client & server in a single script, and use a "special" parameter to launch the server. [This method may have big performance gains, since the OS may reuse the existing code in memory, rather than trying to reread off disk etc]

3) Instead of trying to directly spool to the central server, push updates to a local flat file, then have a daemon script running to watch the local file for any updates, and if found, push them over the wire.

Best of luck, and hope this helps!

Cheers,
Shawn


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 27th, 2009, 6:14 pm 
Offline

Joined: May 23rd, 2009, 4:48 am
Posts: 361
Location: north bay, california
Hey, thanks for the reply,

I'm not sure I agree on what the fundamental issue i'm have is. The latency of the updates determining the order of logging is giving me the problem. I think you're confusing the manner in which my fake server/client instances are communicating.


The core problem the way i see it is this:
All clients are closed, and running "ShopMon.exe Machine Status" logs the status change to Machine.log and updates Machine=Status in ShopMon.ini. This is all local, no network or filesharing issues.
So:
"ShopMon.exe Machine Start"
wait a second
"ShopMon.exe Machine End"

leaves a log like:
timestamp Machine Start
timestamp2 Machine End

But:
"ShopMon.exe Machine Start"
wait a second
"ShopMon.exe Machine Hold"
"ShopMon.exe Machine Start"
wait a 20 seconds
"ShopMon.exe Machine End"

without a delay (enough for the first instance to finish) results in a log:
timestamp Machine Start
timestamp3 Machine End
timestamp2 Machine Hold
timestamp4 Machine End

which means the "status" for that machine during those 20 seconds is logged as Hold, and the log file itself is out of chronological order (even though timestamp3 may = timestamp2)


Re: 1) good idea but i need a more general solution (ie a machine running 1 cycle for 8 hours, with a hold every minute?? maybe a stretch but still... HOLD15435 is a little cumbersome)

re: 2) SendMessage() would be a better solution for my overall network communication model (messages/tcp/ip), but i don't think it will ultimately solve my logging issue, unless i use some IPC between a persistant script and the external program which calls the above command lines (DNC server)

re: 3) again a little confusion to clarify in the way it functions. all updates are logged on the "server" locally, as the script is run from the external app. the only network file access happening is when the "clients" are polling for status changes, to the log file created above


so, again, the real problem is in the logging. which is really a windows issue, which lets the second instance of the app run interrupt the first instance, and complete its function (log) before returning to the first instance and letting it complete.

i guess the proper logging technique would be from a persistent process, but isnt really possibly since such events are instantiated by an external application


thanks a bunch shawn
- joel


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: BrandonHotkey, krajan, patgenn123, wolverineks, Yahoo [Bot] and 62 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group