On Mon, Mar 30, 2015 at 11:06 AM, Bruno Albuquerque <[email protected]> wrote:
> Actually i think I was not clear about what I need. How would I apply
> Err_trap for a higher level function? For example, a call to Indexer_new()
> might fail under some circunstances and the program will exit due to that,
> I would like for it not to exit immediately (for example, to be able to do
> something else if the call fails). indexer_new() does nto accept a context
> and it returns something when it works.
>
> Again, i might just be missing something obvious.

FWIW, Indexer_new() is an example of a sub-optimal API that we should change.
The existing approach is a legacy of Lucy's Lucene heritage.  In Java the
idiom would be to wrap `new Indexer()` in a `try` block, which works fine and
does not leak memory.  What we ought to have instead in Lucy is
Indexer_open(), which returns NULL and sets an error variable on expected
failure cases such as an unsuccessful attempt to acquire the write lock.

By the way, I see you writing to the golang-nuts mailing list and it seems
that you are wrapping the C bindings (presumably from the current 0.4.2 public
release).  You may be interested to know that current Git master has some
proof-of-concept Go bindings, which include `lucy.OpenIndexer()` and an
exception mechanism implemented using Go's `panic` -- including a
`clownfish.TrapErr()` function which takes a Go closure rather than a C
function pointer and context.

But to get back to your question, what you would do is adapt Nick's sample
code to wrap Indexer_new().

    struct IndexerContext {
        Schema       *schema;
        Obj          *index;
        IndexManager *manager;
        int32_t       flags;
        Indexer      *retval;
    };

    static void
    try_indexer_new(void *vcontext) {
        struct IndexerContext *context = (struct IndexerContext*)vcontext;
        context->retval = Indexer_new(context->schema, context->index,
                                      context->manager, context->flags);
    }

    Indexer*
    open_indexer(Schema *schema, Obj *index, IndexManager *manager,
                 int32_t flags) {
        struct IndexerContext context;
        context.schema  = schema;
        context.index   = index;
        context.manager = manager;
        context.flags   = flags;
        context.retval  = NULL;

        Err *error = Err_trap(try_indexer_new, &context);
        if (error != NULL) {
            /* Handle error. */
        }
        return context.retval;
    }

The error trapping code in the lucy.OpenIndexer() Go wrapper is similar:

    
https://git1-us-west.apache.org/repos/asf?p=lucy.git;a=blob;f=go/lucy/index.go;h=f0e09797210253a0e4dde83280f9c49744667aa1;hb=27842415a072d8b8a9f026df1d1f0b2a96b086e3#l76

Marvin Humphrey

Reply via email to