[Development] async operation error guidance

Nehme Bilal nbilal at blackberry.com
Tue Nov 5 19:46:10 CET 2013


For WiFi Direct, I see a similarity with QAbstractSocket API.
Here is the documentation of QAbstractSocket::connectToHost method:
***
void QAbstractSocket::connectToHost(const QString & hostName, quint16 port, OpenMode openMode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol) [virtual]

Attempts to make a connection to hostName on the given port. The protocol parameter can be used to specify which network protocol to use (eg. IPv4 or IPv6).

The socket is opened in the given openMode and first enters HostLookupState, then performs a host name lookup of hostName. If the lookup succeeds, hostFound() is emitted and QAbstractSocket enters ConnectingState. It then attempts to connect to the address or addresses returned by the lookup. Finally, if a connection is established, QAbstractSocket enters ConnectedState and emits connected().

At any point, the socket can emit error() to signal that an error occurred.
***

connected() is emitted only when the async operation is complete, otherwise error() will be emitted.
The error signal delivers a SocketError enum that contains 24 entries. So a single error covering everything is not unusual neither :)

Nehme
________________________________________
From: development-bounces+nbilal=blackberry.com at qt-project.org [development-bounces+nbilal=blackberry.com at qt-project.org] on behalf of Tony Van Eerd [tvaneerd at blackberry.com]
Sent: Tuesday, November 05, 2013 12:02 PM
To: Frank Osterfeld
Cc: development at qt-project.org
Subject: Re: [Development] async operation error guidance

> >
> > It could also fail later, as it is mostly asynchronous. Or it could
> succeed with a result. ie
> >
> >     Q_SIGNAL void deviceConntected(SomeDevice device);
> >     Q_SIGNAL void deviceConnectionFailed(SomeOtherConnectError
> error);
> >
> > or one signal:
> >
> >     Q_SIGNAL void deviceConnectionResult(SomeDevice device,
> ConnectionResult result);
>
> Looking at other async APIs like QProcess and QNetworkReply having two
> signals isn't unusual.
>

Neither case is unusual, from what I can find.  That's the problem! :-(

I don't like a single signal where one param goes unused.
But I don't like 2 signals, where one is not connected to (I've found that people don't bother connecting to the error() signal), and needing to make 2 connections becomes "wordy".


> > Also consider that there are multiple async operations, not just
> 'connectToDevice'.  There is scan, startSession, etc.
> >
> > Should there be a single error() covering everything?  Or one per
> task? Or a way to link the error back to the task?
> >
> >     RequestId startSession();
> >     RequestId startScan();
> >
> >     Q_SIGNAL void error(RequestId requestId, BigSetOfErrorEnums
> error, QString errorStringAsWellMaybe);
>
> Please don't! Such APIs are ugly and hard to use. I'd consider to wrap
> the operations in classes and return them when starting the operation.
> Like QNetworkAccessManager does for QNetworkReply. The returned object
> then handles the state and emit the signals for the particular context.
> E.e. connectToDevice() could return a WiFiDevice or WiFiConnection
> object, which then handles the state for that particular connection.
>

Yes, a Reply object is the other pattern we have used.
One downside is that it means another allocation (or 2 - one for the object, one for the PIMPL)
and it also means someone needs to track/own that memory.
And sometimes another object seems like overkill, if the operation is "simple" (if any async operation can be called "simple").


>
> > - Is "finished()" OK if it didn't _complete_ (successfully) or should
> it be... "ended()" or some better word?
>
> finished() is commonly used also when operations succeed (e.g.
> QNetwork). It shouldn't be too many different signals, otherwise users
> will forget
> to connect to some of the signals.
>

Note also that some Qt APIs only send finished() on success, while others send finished() even after error(). ie you always get a finished().  This is actually good for users that go into a certain state while something is being done - they won't get stuck in that state by missing the end of the state.
But we should be consistent.


---------------------------------------------------------------------
This transmission (including any attachments) may contain confidential information, privileged material (including material protected by the solicitor-client or other applicable privileges), or constitute non-public information. Any use of this information by anyone other than the intended recipient is prohibited. If you have received this transmission in error, please immediately reply to the sender and delete this information from your system. Use, dissemination, distribution, or reproduction of this transmission by unintended recipients is not authorized and may be unlawful.

_______________________________________________
Development mailing list
Development at qt-project.org
http://lists.qt-project.org/mailman/listinfo/development
---------------------------------------------------------------------
This transmission (including any attachments) may contain confidential information, privileged material (including material protected by the solicitor-client or other applicable privileges), or constitute non-public information. Any use of this information by anyone other than the intended recipient is prohibited. If you have received this transmission in error, please immediately reply to the sender and delete this information from your system. Use, dissemination, distribution, or reproduction of this transmission by unintended recipients is not authorized and may be unlawful.




More information about the Development mailing list