I'm watching the config files of my NodeJS server on Ubuntu using:
for( var index in cfgFiles ) {
fs.watch(cfgFiles[index], function(event, fileName) {
logger.info("======> EVENT: " + event);
updateConfigData(fileName);
});
}
So whenever I save a config file, the "change" event is received at least twice by the handler function for the same file name causing updateConfigData() to be executed multiple times. I experienced the same behavior when watching config files using C++/iNotify.
Does anyone have a clue what causes this behavior?
Short Answer: It is not Node, file is really changed twice.
Long Answer
I have a very similar approach that I use for my development setup. My manager process watches all js source files if it is a development machine and restart childs on the cluster.
I had not paid any attention to this since it was just development setup; but after I read your question, I gave it a look and realized that I have the same behavior.
I edit files on my local computer and my editor updates them over sftp whenever I save. At every save, change event on the file is triggered twice.
I had checked listeners('change') for the FSWatcher object that is returned by fs.watch call; but it shows my event handler only once.
Then I did the test I should have done first: "touch file.js" on server and it triggered only once. So, for me, it was not Node; but file was really changed twice. When file is opened for writing (instead of appending), it probably triggers a change since it empties the content. Then when new content is written, it triggers the event for a second time.
This does not cause any problem for me; but if you want to prevent it, you can make an odd-even control in your event handler function by keeping the call numbers for each file and do whatever you do only on even-indexed calls.
See my response to a similar question which explains that the problem is being caused by your editor making multiple edits to the file on save.
Related
I write logging results of working on a data file with my program in a file, which also contains the name of the data file in the log file name, and for reproducibility the data file content is also logged. If the data file is correct, it works OK. If the data file is bad, then the further work is refused; it works fine. In my GUI environment, the user might have a second attempt, and second time provides a correct data file, under a different name. However, the second reading aborts the program, because in the block
google::SetLogDestination(0, LogFileName.c_str() );
google::InitGoogleLogging(FileName);
the initialization command occurs second time. How can I restart, terminate, reinitalize, close, or whatever called, the logging?
Normally, the logging is for the whole program. So, it might log hundreds of interactions with the users (some of which are refused/don't work/etc). You should move these commands to a place where they get invoked once at program startup. They should not be invoked on a per attempt/per user basis.
See docs :
http://rpg.ifi.uzh.ch/docs/glog.html
There are no functions to restart, terminate, reinitalize, or close. You can flush to disk if you are having trouble with buffering, but it sounds like you just didn't understand how the library was intended to be used.
I'm working on a embedded solution where two apps are working: one is the user interface and the other runs in the background providing data for the UI.
Recently I came across with a memory leak or similar error that is making Linux kill the secondary process, leaving the UI in a stopped situation without telling anything for the user about what is going on. I reached the problem by reading Linux's message log file and the software's print on terminal "Kill -myapp".
My question is: how could I notice such an event (and other similar) coming from the secondary software so I could properly report it to the user and log it? I mean, it's easy to have a look time to time in the process 'tree' to see if the secondary app is running and, if it's not, report a "some event happened" in the UI and it's also plausible to have a error-handler system inside the secondary app that makes it write in a log file what just happened and make the UI read that file for new entries from time to time, but how could the UI app knows with better details what is going on in such more abrupt events? (in this case, "Linux killed process", but it could be a "segmentation pipe" or any other) (and if there is another, better solution that this "constant read a log file produced by the secondary app", I'ld also like to know)
Notes: the UI is written in C++/Qt and the secondary app is in C. Although a solution using the Qt library would be welcomed, I think it would be better for the entire programming community if a more generalized solution was given.
You can create a signal handler for POSIX signals such as SIGKILL in the backend process and notify the ui using for example another signal with sigqueue. Any IPC mechanism should work, as long as it's async safe. Read more about signals: tutorial and manual
It may still be a good idea to check from the ui side periodically because the handler might not succeed.
As for a better way to check if process is alive compared to reading the log file:
Check if process exists given its pid
I want to monitor a folder in my file system. Let say I want to monitor the folder: C:\MyNewFolder
I have this code to do it:
HANDLE ChangeHandle=FindFirstChangeNotification(_T("C:\\\MyNewFolder"),FALSE,FILE_NOTIFY_CHANGE_LAST_WRITE);
for(;;)
{
DWORD Wait=WaitForSingleObject(ChangeHandle,INFINITE);
if (Wait == WAIT_OBJECT_0)
{
MessageBox(NULL,_T("Change"),_T("Change"),MB_OK);
FindNextChangeNotification(ChangeHandle);
}
else
{
break;
}
}
I want to have a messagebox that notifying me about any file change in my folder. That code works fine but I have one problem. The problem is that I got 2 notification for each change. What is the problem with my code?
Thanks.
This is entirely normal. A change to a file usually involves a change to the file data as well as a change to the directory entry. Metadata properties like the file length and the last write date are stored there. So you'll get a notification for both. ReadDirectoryChangesW() doesn't otherwise distinguish between the two.
This is not different from a process making multiple changes to the same file. Be sure to be able to handle both conditions. This usually involves a timer so you don't go overboard with the number of operations you perform on a notification. Such a timer is also often required because the process that is changing the file still has a lock on it that prevents you from doing anything with the file. Until the process closes the file, an indeterminate amount of time later.
What you're probably seeing is multiple changes to the one file (e.g. a file being created, and then written to, or a file being written to multiple times, etc). Unfortunately FindFirstChangeNotification doesn't tell you what has actually happened.
You're better off using ReadDirectoryChangesW for file notification as it will actually tell you what has changed.
I have a file open on the iPhone that I am sending the data of across the network (Opened using "_open"). However I have the ability to delete files from the iphone's interface. This is done using NSFileManager's removeItemAtPath.
The odd thing is that removeItemAtPath is succeeding even though the file is currently open.
The file transfers perfectly across the network and removeItemAtPath succeeds before the transfer is complete. So does removeItemAtPath do a lazy delete? ie does it queue it for later if the file is in use? If so then no problems.
If not ... does anyone know how I can get NSFileManager to actually report the fact that it didn't do the delete?
Thanks!
According to the documentation at
http://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/fileManager:shouldRemoveItemAtPath:
shouldRemoveItemAtPath returns YES if the operation should proceed, not necessarily that it already successfully deleted the item. It's also interesting that the documentation states:
Discussion Returning NO from this method causes NSFileManager to stop deleting the item. If the item is a directory, no children of that item are deleted either.
Reading that leads me to believe this is an asynchronous operation and that the return value of this method should not be used to determine if the file was successfully deleted. My guess is that it queues the object for deletion and will be deleted when the file is no longer in use.
I'm writing a program that among other things needs to download a file given its URL. I'm too lazy to implement the Http/Https protocols manually, so that I needed some library/object/function that'll do the job.
Critical requirement: The download must be asynchronous. That is, the thread that issued the download must be able to do something else "while" downloading the file, plus the download must be able to be aborted anytime without any barbaric side effects (such as internal call to TerminateThread).
Nice-to-have requirements:
Should be able to download the file "into memory". Means - read the contents of the file as they arrive, not necessarily save it into some "file system" file.
It'd be nice to have some convenient Win32 progress notification mechanism (waitable event, semahpore, completion port, etc.), rather than just periodically polling the download status.
I've chosen the XmlHttpRequest COM object to do the work. It seemed to work fine enough, plus it supported asynchronous mode.
However I noticed that after some period it just stops working.
That is, after several successful file downloads it stops downloading anything.
I periodically poll it to get its status, it reports "in-progress", but nothing actually happens, and there's no network activity. Moreover, when the same process creates another instance of XmlHttpRequest object to perform new downloads - the effect is the same. The object reports "in progress", whereas it doesn't even try to connect to the server (according to network sniffers and system TCP state).
The only way to make this object work back is to restart the process. This makes me suspect that there's a sort of a bug (sorry, I meant undocumented feature) in the object. Also it's not a bug at the level of an individual object, since the problem persists when the object is destroyed and another one is created. It's probably some global state of the DLL that implements this object.
Does anyone know something about this? Is this a known bug?
I'm pretty sure there's no chance that I have another bug in my code, because of which it seems to me to be the bug is in the XmlHttpRequest. I've done enoughtests and spent time with the debugger to conclude without reasonable doubt that it's just the object stops working.
BTW, while the object should work, I do all the waiting via MsgWaitXXXX API calls. So that if this object needs the message loop to work properly (for instance, it may create a hidden notification window and bind it to a socket via WSAAsyncSelect) - I give it the opportunity.
I know from my own experiences that the Microsoft implementation of the XmlHttpRequest falls short of full compliance with the draft standard. In particular the standard mandates that streamed data should be able to be extracted in ready state '3' (Receiving) which IE deliberately ignores.
Unfortunately I have not seen what you are describing despite using XmlHttpRequest objects extensively for long polling purposes.