Recently I needed to make a server application run as an Unix daemon and be able to start, stop and restart it on demand. The application I’m talking about didn’t have any startup/shutdown utilities analogous to for example Tomcat. It run as a script, without even detaching from the console. At first I figured I’ll have to write a utility application that would start the process, store it’s PID in some file and somehow “daemonize” the forked process. So as always before doing anything, I decided to check if anyone hasn’t done that before me. I wasn’t really surprised when a quick Google search allowed me to find a utility written by someone just for that and even more. The application is called start-stop-daemon and should be installed by default on almost any Linux (well, it certainly was on my Ubuntu 7.10).

Below is a quick tutorial on how to start any server application as a Unix daemon on system startup. It was tested on Ubuntu Linux version 7.10 (Gutsy Gibbon), but it should work on most Linux distributions, and certainly on those which are Debian based.

Let’s assume that the application we want to run is /path/to/script/app.sh

First, we need to create a script in /etc/init.d/ Let us name the file /etc/init.d/app

The file contents would look something like this:


#!/bin/sh

PATH=/bin:/usr/bin:/sbin:/usr/sbin

case "$1" in
start)
echo "Starting application"
start-stop-daemon -d /path/to/script -c username --start -b -m -p /path/to/pid/app.pid --exec /path/to/script/app.sh
echo "Started."
;;
stop)
echo "Stopping Application"
start-stop-daemon -d /path/to/script --stop -p /path/to/pid/app.pid
rm -f /path/to/pid/app.pid
echo "Stopped."
;;
restart)
sh $0 stop
sh $0 start
;;
*)
echo "Usage: app {start|stop|restart}"
exit 1
;;
esac

exit 0

This is a pretty standard service startup/shutdown file. The most interesting part of this script is the use of the start-stop-daemon application. This line:

start-stop-daemon -d /path/to/script -c username --start -b -m -p /path/to/pid/app.pid --exec /path/to/script/app.sh

starts the process as a daemon. The -b option makes the process run in background, the -m option is used to create a PID file, -p specifies where the PID file is located (the directory where the file is located must already exist, as it won’t be created automatically), -d specifies the current directory that will be seen by the script, -c changes the process owner. The start-stop-daemon application will check for PID file when starting, and won’t start the script if process with this PID exists. If the script for some reason fails to start, or encounters an error, the PID file won’t be deleted, so keep that in mind. This technique is certainly not for general-purpose usage - it should be used only when you don’t have any other way to properly startup your server (or maybe if you are just looking for a quick-and-dirty solution).

I figure that the line that stops the daemon does not need more explanations. Just note that the PID file is deleted manually after stopping the service - start-stop-daemon won’t do that for you.

Now we just need to make the application automatically start at system startup:

sudo update-rc.d app defaults

You can start/stop/restart the server the same way you would do it with for example Apache:

sudo /etc/init.d/app (start|stop|restart)

Hope you’ll find this trick helpful:)

Psyho

Share/Save/Bookmark

Posted in linux at April 19th, 2008. by Adam 'Psyho' Pohorecki 2 Comments.

I’ve recently watched a great presentation by Venkat Subramaniam titled “Pragmatic factors for Agile Success“. It’s about one and a half hours long, but if you’re doing agile project management in your company, I believe you should definitely watch it. Venkat talks about some good and bad practices, and mostly deals with communication issues. The presentation is cleverly organized into parts, each of which having two sides of it’s own - one beginning with a little devil saying some stuff (the bad practice) and the other one with a little angel saying how the things should work.

The part of the presentation, which in my opinion got the most attention from the audience (and myself), was the part where Venkat talked about the idea to criticize ideas and not people and dealing with communication between team members in general. I believe that this part is highly relevant to lots of people, because the every day communication is possibly the hardest thing to get right in any team. I strongly support the ideas of egoless programming and making design (or for that matter any other kind) decisions based solely on the solutions merits and drawbacks. The latter is the idea that I’d like discuss a little bit more in this post.

I think that although picking some solution based solely on it’s advantages and disadvantages is the only logical thing that comes to mind, I disagree that it is possible to just “let go” of the idea’s ownership. Of course you should go ahead anyway and try not to think about the solution in terms of “my idea” or “someone else’s idea”, the problem is that no matter how hard you try there is just no possibility of really doing that. Sure, you can release the idea, no longer considering “yours”, but if you have already put a substantial amount of thought into it, it’s become a product of your knowledge, experience, your character and beliefs. Your idea is yours not because you consider it yours or not, it’s yours because you’ve made your mark on it.

Hardly ever do you encounter a problem which solutions can be objectively evaluated to pick the best one. Most of the decisions we make are made totally subjectively. Of course in software design the subjectivity level is lower than in for example making business decisions, but it’s still there. From my experience, the area in software design that raises the most controversy is user interface design. The reason for that is that in user interface design you often base your opinions on your own preference. Something that is unintuitive for one person may be perfectly intuitive for another. Other design decisions can be evaluated a little better - something either handles concurrency, or it doesn’t, it handles all the functional and non-functional requirement’s or it doesn’t. However, even if you created a list of facts about some design, which are objectively true, people still can differ about how important those features are, as advantages or disadvantages. What I’m saying is, even when everybody in the team is perfect and letting go of the idea ownership - it’s still pretty hard to arrive at a conclusive decision without someone coming and saying: “OK, I’ve heard all your arguments - let’s do it this way” and ending the discussion. It’s not anybody’s fault - it’s just human nature.

In Agile the communication between the team members is of utmost importance. It’s really hard to succeed if you can’t talk with your team, so we should all try our best and learn communication skills. But if you have a colleague, that disagrees with your opinions and criticizes your designs, don’t think that you’ll change this by just changing the way you speak to that person. You have to understand that the differences between you will still be there, and you’ll still disagree with each other, but that’s the way it should be. The key is to seek those differences, because you might learn from them, and when you still disagree at the end of the day - just learn to let go, sometimes the other persons idea is different, but just as good.

Psyho

Share/Save/Bookmark

Posted in agile, project management at April 16th, 2008. by Adam 'Psyho' Pohorecki 4 Comments.

Not everybody knows that you can specify for some ant targets to run only when some set of files was updated. It is particullary useful when working with GWT or Ivy.

In my GWT projects I usually have tasks like run-shell (which runs a hosted-mode browser) and compile-gwt (which runs the GWT compiler). The run-shell task depends on the compile-gwt task, but this would cause my GWT code to be recompiled every time I run the hosted browser. You may ask - why would you even rerun GWT shell, if you didn’t modify any of the GWT source files? The answer is quite simple - sometimes you don’t make any changes on the client, but only on the server-side and wan’t to see how these changes affect the client. Or maybe you just don’t want to recompile your GWT code every time you need to create the .war file and deploy your application or run ivy:retrieve everytime you run your build script. Anyway, I find this trick pretty usefull.

So how does the magic hapen? The whole trick is possible thanks to Ant’s uptodate core task. Below is the snippet from the example build.xml file:


<uptodate property="gwtBuild.notRequired"
    targetfile=".gwtBuild">
        <srcfiles dir="src"/>
</uptodate>

Uptodate task sets Ant property (here called “gwtBuild.notRequired”) when targetfile is newer (more up-to-date) than any of the files in the srcfiles fileset. Here I’m comparing it to the all directory contents, but srcfiles is a normal ant fileset so you can always use include and exclude tasks within. You can also use mapper subtask instead of targetfile for more complicated use cases.

So now that we know how the magic is done, it’s time to put it to a good use:


<target name="compile-gwt" unless="gwtBuild.notRequired">
    <!-- invoke the GWT compiler here -->
    <touch file=".gwtBuild"/>
</target>

The touch target will create .gwtBuild file if it doesn’t exist or update it’s last modified time otherwise. It should be invoked after the compilation succeeds, bacause if it wasn’t, in case of compilation failure the target would not be executed again unless any of the source files was modified. The “compile-gwt” target will execute only if the gwtBuild.notRequired property is not set thanks to the “unless” attribute.

Now for the finishing touch we need to delete the flag file in our clean task:


<target name="clean">
    <!-- Delete the flag file for compile-gwt -->
    <delete file=".gwtBuild"/>
    <!-- Delete other files and directories -->
</target>

To illustrate usage of this technique I’m attaching to this post a simple GWT project with an Ant script. The project was tested on Windows with GWT 1.5M1 and GWT 1.4.61. To run it simply change the gwt.home property in build.properties file to point to your GWT installation directory.

Click here to download sample project

Hope you’ll find this tip usefull:)

Psyho

Share/Save/Bookmark

Posted in ant, gwt at April 2nd, 2008. by Adam 'Psyho' Pohorecki 1 Comment.