2

I need to execute several matlab functions on a daily basis. Some of these functions download data from the internet. They fail if the data is not ready yet for example and I want them to try again after some time. In order to implement this I have a python script calling the matlab functions several times until success or send me an e-mail if they fail repeatedly. Probably not the "state of the art" implementation but I don't know better. The python script is called each day by a daemon. Now, this works if I'm logged into the computer but fails with return value 1 and following message (daemon error log) when the computer (imac) rests for a while (I forbid it to sleep though in the energy saver preferences. At least I think I did by ticking "Prevent computer from sleeping automatically when the display is off". However, "Enable Power Nap" is on.)

Traceback (most recent call last):
  File "/Users/<username>/Documents/daemontest/matlab_batcher.py", line 108, in <module>
    eng = matlab.engine.start_matlab()
  File "/Library/Python/2.7/site-packages/matlab/engine/__init__.py", line 92, in start_matlab
    eng = MatlabEngine(option)
  File "/Library/Python/2.7/site-packages/matlab/engine/matlabengine.py", line 230, in __init__
    self.__dict__["_matlab"] = pythonengine.createMATLAB(tokens)
matlab.engine.EngineError: MATLAB process can not be created.

Matlab writes a crash dump with segmentation violation (with which I cannot do anything myself).

I guess that the computer somehow goes to sleep anyway and that it cannot start matlab then. Could this be the case? If so, how can I prevent it from sleeping or configure it to wake up to start the daemon?

I searched for the keywords and the title-question in different varieties in google and read through various suggested topics here on stack exchange. In the docu about the mathwork license manager I found that maybe I have to start a matlab daemon before I can call matlab. However, I don't really understand what the lm-libraries in the matlab distribution do and I hesitate to run them.

This is a copy of my plist (stored under /Library/LaunchDaemons) that I wrote based on this launchd Tutorial:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>org.<app_name>.testDaemon</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/bin/python</string>
                <string>/Users/<username>/Documents/daemontest/matlab_batcher.py</string>
        </array>
        <key>StandardOutPath</key>
        <string>/Users/<username>/Documents/daemontest/test.stdout</string>
        <key>StandardErrorPath</key>
        <string>/Users/<username>/Documents/daemontest/test.stderr</string>
        <key>WorkingDirectory</key>
        <string>/Users/<username>/Documents/daemontest</string>
        <key>StartCalendarInterval</key>
        <array>
                <dict>
                        <key>Hour</key>
                        <integer>16</integer>
                        <key>Minute</key>
                        <integer>0</integer>
                </dict>
        </array>
        <key>KeepAlive</key>
        <false/>
</dict>
</plist>

Storing the plist under ~/Library/LaunchAgents actually works as well as long as I'm using the computer. I moved the plist to /Library/LaunchDaemons because I thought these also run when another user is logged in or when the computer is running but nobody is using it. I'd very much appreciate your help.

I would actually like to run the daemon under a different user account than my working account but I failed with my trial where I copied the working directory and changed the file paths to the other user account and added the key username to the plist. The daemon did not even start but returned 78 instead (I didn't find out what this exit value might mean). This is a bit off topic but I'd appreciate comments on this if you have suggestions anyway.

mabe
  • 125
  • 1
  • 10
  • Two things. First, cron can handle this all for you. Doing it manually with Python will be much more work. Second, if you are already using Python, why are you downloading stuff using MATLAB to begin with? MATLAB is great at a lot of things, but web-based stuff is not one of them. On the other hand Python excels at web-based stuff. And it is a ton of unnecessary overhead to start a MATLAB session just to do some downloads. So you are much better off using Python for the downloads directly. – TheBlackCat Jul 30 '15 at 09:55
  • Thanks for the comment! – mabe Jul 30 '15 at 09:58
  • You mean downloading data and sending mail upon failure can be handled by the launchd job (cron is not recommended anymore)? To the second: Matlab also does some computations with the downloaded data so I have to start matlab anyway with the daemon. I'll probably end up migrating the matlab code to python or java sooner or later but for now my job is to replace the very unreliable matlab timers with something more stable (if possible). – mabe Jul 30 '15 at 10:08
  • I know that you can do it in cron, I don't know about launchd. – TheBlackCat Jul 30 '15 at 10:18

1 Answers1

0

Finally figured out a solution, well, rather a work around.

In the python script I was using MatlabEngine by matlab. Apparently this only starts when the user is active. The details I still don't know but must be something ado with the matlab license and the model the imac switches to a few minutes after the user becomes inactive. Would be interesting though to understand this properly...

What actually works is to use bash commands instead of the MatlabEngine for calling matlab. This doesn't offer the direct interaction with matlab function as the MatlabEngine but for my case totally sufficient.

mabe
  • 125
  • 1
  • 10