KExtProcess Documentation

When I started to write yesterday's blog I planned to add all kind of information about KExtProcess. It turned out that my blog became pretty big when I was only about halfway the stuff I planned, so I changed plans and promised some extra updates this week.

So here comes the first bonus chapter: documentation.

The main documentation source for KExtProcess, besides reading the code, are the API docs. I have the fortunate habit of adding small pieces of documentation to all methods I write using pseudo-apidox style syntax. Although I never tried to actually run Doxygen over them they turned out to be quite useful as a starting point. So when Adriaan de Groot started his 'ApiDox Crusade' I pointed out KExtProcess to him and he was kind enough to add it to his script that generates the docs.

Because Adriaan hosts the API docs on his personal ADSL line he asked me not to link directly to the English Breakfast Network and instead put the docs up on another server. You can find the docs here, thanks to Matt Douhan for offering me hosting and bandwidth on one of his servers. Both of you, be sure to ask me for a drink whenever we meet again, the service is much appreciated!

Besides the API docs there are the example programs. They are quite small and should therefore be relatively useful. What's missing is a porting guide from 'normal' KProcess to KExtProcess. I could go into all details of KProcess, but if you use it in the most common way within KDE your code probably looks like this:

KProcess *proc = new KProcess( this );
*proc << "tail";
*proc << "-f";
*proc << "/var/log/messages";

proc->start( KProcess::NotifyOnExit, KProcess::All );

connect( proc, SIGNAL( processExited( KProcess * ) ),
this, SLOT( slotProcessExited( KProcess * ) ) );
// And connect the other slots, etc.

This should look pretty familiar, right? KExtProcess consists of more than one class and is therefore contained in a namespace. Taking this into account, porting to a local KExtProcess can be as easy as adding the right namespace and replacing 'KProcess' with 'KExtProcess':

KExtProcess::LocalProcess *proc = new KExtProcess::LocalProcess( this );
*proc << "tail";
*proc << "-f";
*proc << "/var/log/messages";

proc->start( KExtProcess::ExtProcess::NotifyOnExit, KExtProcess::ExtProcess::All );

connect( proc, SIGNAL( processExited( KExtProcess::ExtProcess * ) ),
this, SLOT( slotProcessExited( KExtProcess::ExtProcess * ) ) );
// And connect the other slots, etc.

I don't think I'll be able to make porting easier than that, apart from ditching namespace, which I am not going to do for reasons which become more apparent if you start using the additional features that KExtProcess offers.

Take for example Profiles. If you want to give the user control over where and how to run the process, just add a combo box that shows all available profiles:

QStringList profiles = KExtProcess::Profile::profileList();
for ( QStringList::ConstIterator it = profiles.begin(); it != profiles.end(); ++it )
m_mainWin->m_profileList->insertItem( *it );
m_mainWin->m_profileList->setSelected( 0, true );

Once the user has selected a profile change the line that creates the LocalProcess above into the following four lines:

KExtProcess::Profile profile( 0L );
profile.load( m_mainWin->m_profileList->currentText() );

KExtProcess::ProcessFactory *factory = KExtProcess::ProcessFactory::self();
KExtProcess::ExtProcess *proc = factory->createProcess( &profile, this );

Not very difficult. And I have some ideas to make this even simpler. Probably in KExtProcess 0.5 you can suffice with the following whopping two lines of code to instantly make your application work on remote systems:

KExtProcess::Profile profile( m_mainWin->m_profileList->currentText() );
KExtProcess::ExtProcess *proc = KExtProcess::ProcessFactory::createProcess( &profile, this );

This simplicity is why I consider KExtProcess so cool: existing code can be changed with incredible ease. As long as you have an actual use for remote process execution there is no reason for not trying KExtProcess. Which brings us nicely to one of the next episodes: possible uses for KExtProcess. Stay tuned :)


Please consider renaming ExtProcess to ExtendedProcess. Why? Because
ExtProcess could be confused for meaning ExternalProcess as opposed to LocalProcess, especially by mathematicians where ext usually stands for the exterior of a set. Maybe it's just me, but I really dislike abbr. class and method names.

Alternatively, if KExtProcess doesn't add too much overhead then I suggest simply replacing KProcess by KExtProcess. (You probably already intend to do this, but I didn't see you explicitely stating this intention.) Since KExtProcess::LocalProcess seems to be a full replacement for KProcess keeping both doesn't make any sense. After all we want to clean up the API in KDE 4 and not add more duplication.

By Ingo Klöcker at Tue, 08/16/2005 - 08:21

Renaming to ExtendedProcess might make sense. When I came up with the name 3 years ago I tended towards shorter names than I do now with modern editors and tab completion.

However, I haven't made up my mind yet as for whether to replace KProcess in KDE 4 or not. As you can see in the API docs for LocalProcess I am considering it, but it's not a real goal as long as

1. KExtProcess is not mature enough to be a viable replacement
2. it requires that KExtProcess is finished by KDE 4, which is a promise I can't really make given scarce spare time
3. I didn't contact the current maintainer of KProcess (Oswald?) yet, and I would still need the maintainer for all the gory internals of current KProcess
4. No apps are using KExtProcess yet, making a move to kdelibs a no-go anyway

So yes, I am considering it, but until apps start using it and I get some better overview of how much work is left I don't want to propose it for KDE 4 yet.

In the meantime, I could rename it I guess. For the KDE 3.x series this is the only viable option anyways, and since KDE 3.x has still a long way to go and deserves better tools for admins and developers before KDE 4 is there I'm strongly inclined to have at least one more KDE 3 release, possibly even much more.

By Martijn Klingens at Tue, 08/16/2005 - 08:37

I was going to suggest that in my comments on the other post, but just as this post spilled over, I guess so did my comment. ;)

Does it have to be ready for KDE 4.0? I'd take as much time as needed, to make sure the interface was right before replacing it... potentially during a later 4.x release?

I'm not sure how the C++ ABI works, so this may not be feasible. But, as long as it is, it seems the best solution.

By you at Tue, 08/16/2005 - 14:16

That won't work the same way. We can add libkextprocess to kdelibs perfectly fine for KDE 4.x, but although KProcess and KExtProcess::LocalProcess have been designed to be almost source compatible, they are not at all binary compatible. As a result, we wouldn't be able to drop KProcess, at best it could be turned into a wrapper, i.e. making KExtProcess::LocalProcess the real class and KProcess the proxy instead of vice versa.

What *may* be possible if we decide to go this route early on is to change KDE 4's KProcess such that it actually will be binary compatible. To do this at least parts of the namespacing will have to be included in KDE 4.0 without having the full library there (yet).

However, I actually think it will be impractical to ditch KProcess for real. It would require fixing a lot of KDE code that would have to switch to KExtProcess. On the other hand, Mahoutsukai is right that KDE 4.0 is the opportunity to clean up the API.

By far the easiest would be to make sure that we invest enough manpower (mine or someone else's) into KEP before, say, januari, to call KEP '1.0' by then. That would still leave enough time for KDE 4. If KEP isn't 1.0-worthy at new year's day then the time window for making it the replacement of KProcess is basically over, the next bet would be to have the two coexist.

I can't predict whether that's a realistic time window though. Depends a lot on my work and whether or not a developer community will form around KEP or not. Until now I wanted to remain the sole developer, only since last weekend I'm ready for accepting others.

By Martijn Klingens at Tue, 08/16/2005 - 18:14