Comment on code
Charles Yeomans
charles at declareSub.com
Thu Dec 7 16:07:04 CST 2006
On Dec 7, 2006, at 3:58 AM, Ruslan Zasukhin wrote:
> Hi Charles,
>
> Your test project have this function.
>
> -------------------------------------
> Sub Action()
> dim connection as new VConnection("localhost", "sa", "sa")
> connection.Open
> dim db as new VDatabase(connection)
> db.Open new FolderItem("pastefforts")
>
> dim c as VCursor = db.SQLSelect("SELECT recID, * FROM Decisions
> WHERE
> recid < 400", EVCursorLocation.kServerSide, EVLockType.kReadWrite,
> EVCursorDirection.kRandom)
>
> if c.FirstRecord then
> do
> if not c.BlobField("notesStyleData").IsNull then
> dim styleData as String = c.BlobField
> ("notesStyleData").ReadRawData
> end if
> loop until not c.NextRecord
> end if
> c = nil
> db.Close
>
> exception oops
> break
> ---------------------------------------------------------
>
>
> This code contains at least 2 not obvious mistakes.
>
> 1) connection is never closed and destroyed.
>
> so when I try reproduce your few-clicks issue,
> I simply get in server log that connections are eaten to zero,
> and then server refuse connection.
>
> actually IT IS STRANGE that connection object not dies
> on function exit. As I understand RB should kill connection
> object.
> right ?
>
RIght -- depending on your implementation. Here, connection, db, and
c are all local variables, so when the method exits, the objects to
which they point will be destroyed. I just did a little test --
Sub Action()
dim connection as new VConnection("localhost", "sa", "sa")
connection.Open
exception oops
break
End Sub
The server log shows that the connection is closed when the object is
destroyed.
But now, consider the following code.
dim connection as new VConnection("localhost", "sa", "sa")
connection.Open
dim db as new VDatabase(connection)
db.Open new FolderItem("testDB")
db.Close
exception oops
break
Executing this code repeatedly, I exhaust the available connections.
V4Rb raises exception 533781, ERR_CONNECTION_BROKEN_RECEIVED_PACKET.
But the server log shows Connection request rejected: ERROR #533761:
Connection limit reached. I'll suspect a typo in the V4Rb client code
explains the difference in errors. The server log shows that the
database is being closed on the server (even if I omit the db.Close
call)
When I quit the app, all of the connections are released.
This code also closes the database and releases the connection.
dim connection as new VConnection("localhost", "sa", "sa")
connection.Open
dim db as new VDatabase(connection)
db.Open new FolderItem("testDB")
connection.Close
exception oops
break
So it appears that if I open a connection, then use that connection
to open a database, then close the database, the connection object is
not informed of the database being closed. The result is that the
connection is not closed when the VConnection object is destroyed.
In the short run, we can work around this by closing the connection
explicitly. But I don't want to do that, because I am lazy and
prefer to load as much work onto the REALbasic framework as possible.
>
>
> 2) this code is not safe from point of view of exception throw.
> look.
>
> If in loop any method will throw exception, then you will go into
> last 2
> lines of code. But lines
>
> c = nil
> db.Close
> connection.close
> connection = nil
>
> Never will be executed. You see?
>
Yes. But from my point of view it is exception-safe to the extent
that I trust the REALbasic runtime framework, because DB.Close and
connection.Close should be called in the object destructor. Indeed
it may be better, because exception handling is a little broken right
now in Mach-O builds.
>
> SAFE code must have such finalization code in both
>
> normal branch
> exception branch
>
> May be realbasic have like Java keyword: 'final' ?
>
REALbasic has a Finally block that allows you to do this.
Charles Yeomans
More information about the Valentina
mailing list