On Mon, Aug 31, 2009 at 12:04 PM, Eric Day<[email protected]> wrote:
> Hi Ross,
>
> On Sun, Aug 30, 2009 at 05:45:39PM -0700, Ross McFarland wrote:
>> a follow up to this portion after some more experimenting.
>>
>> it actually doesn't seem to be possible to reuse result objects b/c of
>> this issue. when i create a result with drizzle_result_create i can't
>> call drizzle_result free on it between calls to drizzle_query_str with
>> it or else the object i'm using goes away. there doesn't seem to be a
>> way get rid of the reference in the connection object without getting
>> rid of the result object itself. how would language bindings handle
>> this:
>>
>> {
>> DrizzleConnection con;
>> DrizzleResult r;
>>
>> ...
>>
>> con.query("select foo", r);
>> ...
>> // there doesn't seem to be anything i can call here to get the
>> reference to
>> // the underlying c object in r to be removed from the object under con's
>> // list
>> con.query("select bar", r);
>> ...
>>
>> // con goes out of scope and double free's result
>> }
>
> Just put a drizzle_result_free() in between? You could add a higher
> level function:
>
> r.reset();
>
> Which would do any high level cleanup and call drizzle_result_free. If
> you want this to not be required, you could do a bit more magic and
> in con.query() detect if r is already initialized, and if so, call
> drizzle_result_free there. Not clean, but requires nothing extra in
> the higher level language.
actually i don't want this to work as i don't think the library should
be tracking object relationships for any purpose other than needing
the access to information. i was just replying b/c one of the previous
messages said this was a problem with the way the library uses stack
allocated objects, but it appears that it doesn't matter if it's stack
allocated or (library) malloc'd. in fact it's worse with malloc'd
object b/c there's no fix, you have to use fresh objects every time.
my suggestion at this point is to get rid of all of that stuff from
libdrizzle and if people want/need it to create a higher level
library that does that management for you:
loosely something like:
typedef struct _DrizzleManagedConnection {
DrizzleConnection connection;
DrizzleManagedResults manangedResults[];
} DrizzleManagedConnection;
that way most clients aren't paying for what they won't make use of.
---
true ref-counting fixes a lot of these issues. though i still don't
think it should be used to implement the managed memory. however, it
is a 'correct' way to handle the management of objects when they can
internally refer to each other and potentially need to outlast the
scope they were created in. (a query will always need a reference to
the connection from which it reads data, even if that connection is no
longer in the client's scope...)
doing this correctly fixes a lot of the hard to find & fix problems
that people are going to run in to, but has it's own issues
(ref-counting bugs can be hard to track down.) so i'm torn on whether
or not it's a good idea. this is especially complicated by stack
objects which you can't keep around when they go out of scope.
that said, if libdrizzle doesn't do it every single language binding
and non-stack-based real-world client is going to have to do it on
their own. maybe it's another candidate for a wrapper like the managed
stuff above (DrizzleRefCountedConnection) in reality i think it will
be necessary in many cases.
---
so what i currently think is the best path forward:
base client library:
- dirt simple non-allocating (stack or externally allocated object)
- no memory tracking or management, up to client to get lifetimes right.
- clean oo-ish semantics
- a bare minimum of api (no two ways to do one thing) supports the
most common
use-case really well,
- you can get a tour of the majority of the (main) api you're
supposed to use in a
simple 100 line example.
- default use case doesn't do connection pooling
- connection is the base object
- you don't pass a drizzle object in to it, one is not created by default
- this prevents the penalty of drizzle objects when they aren't desired.
additional functionality in inherited/wrappers
-can live in the same library (libdrizzle,) just not involved in
paths without explicitly asking
- library allocating w/ref-counting
- does library allocs and ref-counting for you
- useful to most language bindings and non-trivial native
clients, probably used a lot
- connection pooling
- adds in the drizzle object (though i think it should be called
ConnectionPool)
- see my response to the other email in this thread (once i get
a chance to sit down
and write it) as to why i don't think this belongs in the
default path of libdrizzle.
i realize this probably is a big departure from the current library
and i've only successfully conveyed to you or convinced you of a few
of the problems i see with it, but i wanted to list out what i think
should exist for posterity and for you and others to comment on.
if it's felt that the current api/path is too well established to
pursue something like this then i'll stop trying to push it and let
things continue with my thoughts/feedback well heard. i'd be happy to
continue discussion if questions are asked.
even if that's the case i don't think i'd try to create a (competing)
library, unless others showed significant interest in it. in the end
the only thing that matters is that people people can use drizzle to
it's potential. it's entierely possible that others won't see problems
i find in libdrizzle and even if they do can successfully navigate
them without too much trouble.
best,
--
-rm
_______________________________________________
Mailing list: https://launchpad.net/~drizzle-discuss
Post to : [email protected]
Unsubscribe : https://launchpad.net/~drizzle-discuss
More help : https://help.launchpad.net/ListHelp