API robustness - (was: Different ways to create a directory)

David Faure faure at kde.org
Fri Aug 14 12:16:34 BST 2009


On Friday 14 August 2009, Rafael Fernández López wrote:
> On Friday 14 August 2009 12:04:11 David Faure wrote:
> > On Friday 14 August 2009, Rafael Fernández López wrote:
> > > >  in the Qt one. So the fix is not KDE5, but adding mode_t to
> > > > QDir::mkpath() so that we can get rid of KStandardDirs::makeDir.
> > >
> > > Yes, that is what I meant. KStandardDirs::makeDir can be removed.
> > 
> > ... only once you make a Qt merge request that adds mode_t support to
> >  QDir::mkpath() (but this can be done today, no need to wait for KDE 5 for
> >  that bit. Then we can deprecated KStandardDirs::makeDir and port the code
> >  to mkpath, without waiting for kde 5 either.)
> 
> I don't see this. The mode parameter can be perfectly added to KIO or 
> NetAccess.

It's already there. But from inside kdecore we need an mkpath-with-mode
functionality... that one cannot use kio.

> If we add it to QFile we are limiting ourselves to local 
> filesystems. And note that the flag I meant is not the "mode" (the permissions 
> given for the new directory) but for completing the path if some directories 
> do not exist, that is the particularity of KStandardDirs::makeDir, even more 
> than the mode itself.

Yes, we could have KIO::mkdir( ... CreateMissingParents), of course, but
that doesn't solve the synchronous local-dirs issue.

> > There is nothing hard about calling exec().
> > I think you're missing the point that I wanted to make: I agree, a sync api
> >  is sometimes useful (in apps that are not complex enough to break on
> >  nested event loops...). I'm just saying that instead of the one-line
> >  NetAccess::mkdir you can use the two-line KIO::mkdir + job->exec(). That's
> >  a great step forward in removing the number of available APIs for doing a
> >  given operation, you should be all in favour of it, I would think :)
> 
> Yes. But we both know that we would not do it, and we would use NetAccess 
> instead because it would not block GUI (using a dangerous event loop, OK, but 
> would not block GUI).

!?!? exec() and NetAccess have the *exact* same effect.
They create a nested event loop, which runs timers and sockets and lets the
GUI repaint, but they both block user interaction with the GUI (otherwise
it would be even more dangerous in terms of re-entrancy).

> Here you absolutely misunderstood me, and supposed I was talking about the 
> synchronous API. What I wanted to show is that:
> 
> KJob *makeDirRemote = KFoo::makeDir("ftp://foo:bar@host/myDir");
> KJob *makeDirLocal = KFoo::makeDir("file:///home/user/myDir");
> 
> would be the ideal thing. Since the developer has not to care about what's 
> going on behind the scenes.

OK. Well, we already have that, it's KIO::mkdir. But if you have to convince
every developer that in order to do a stupid always-local mkdir they have
to use asynchronous API, well, good luck. I certainly wouldn't want to do that.

> So the developer can _always_ trust that KFoo::makeDir will do the right 
> thing. He can give it a ssh, ftp, file, sftp, ftps protocol, that internally 
> it will do whatever is necessary for the operation to succeed.

Yep, already the case with KIO. Doesn't cover all use cases though.

> Internally, KFoo::makeDir could check scheme() for being QString() or "file", 
> and in that very case, use QDir internally. I don't see any problem there, and 
> would make "one point of contact only" with the outside developer for creating 
> a dir.

The problem is forcing people into an asynchronous API when they DO NOT EVER NEED IT
(as it the case with always-local files).

Ask Edulix if he would like to rewite the KonqSessionManager code (which works
on local files storing konq session) based on async apis only...

Ask Robert to port the konsole code that reads like this
./src/ProcessInfo.cpp:392:        QFile statusInfo( QString("/proc/%1/status").arg(pid) );
./src/ProcessInfo.cpp:421:        QFile processInfo( QString("/proc/%1/stat").arg(pid) );
./src/ProcessInfo.cpp:491:        QFile argumentsFile( QString("/proc/%1/cmdline").arg(pid) );
./src/ProcessInfo.cpp:515:        QFileInfo info( QString("/proc/%1/cwd").arg(pid) );
./src/ProcessInfo.cpp:541:        QFile environmentFile( QString("/proc/%1/environ").arg(pid) );
./src/ProcessInfo.cpp:695:        QFile psinfo( QString("/proc/%1/psinfo").arg(pid) );
./src/ProcessInfo.cpp:730:        QFileInfo info( QString("/proc/%1/path/cwd").arg(pid) );
to a KIO::storedGet and moving the parsing code to slots, and having a slotResult, etc.

This is all a lot more work, and for what? For not using QFile/QDir which are available
and do the job faster and simpler? Sorry, this is nonsense.
There is a use case for KIO, and there is a use case for QFile and QDir.

It's hard enough to convince everyone to write async code for the case where it *is*
needed (kio jobs), there's no point in also forcing everyone to write async code in
the case where they *clearly* don't need it.

> Yes, but only because you have supposed that I was talking about the 
> synchronous API

OK, sorry about that; the code sample wasn't clear.

-- 
David Faure, faure at kde.org, sponsored by Qt Software @ Nokia to work on KDE,
Konqueror (http://www.konqueror.org), and KOffice (http://www.koffice.org).




More information about the kde-core-devel mailing list