On 01/03/2014 04:39 PM, Sergey Mironov wrote:
Here is how I view the uw_trigger_task("name_of_task") you are suggesting:
[...]

This time JobFFI.run remembers task name and calls uw_trigger_task
upon completion. Do I understand your idea correctly?

Yes, that's what I meant.

I have doubts. In my view, the whole concept of tasks is a kind of
compromise. It covers some certain cases of server-side procedures
without introducing a  low-level bindings to operating system's API of
threads, processes, signals and everything. It is simply not possible
to cover all cases with tasks. You as an author should stop extending
it in some point and say "everything else is beyond the scope of
Ur/Web, use FFI if tasks are not enough". And, in fact, you did it.

I can certainly see the appeal of that position, especially to me. ;)

I think it is better to direct efforts into improvement of the FFI
interface and urweb API because we will need them anyway. If I only
had methods for

1) clone the context to use it with a new thread inside an FFI
2) call the url handler (I already know that `uw_begin' or
`uw_get_app(ctx)->handle(ctx, uri)' may help me here)

I think I'm basically on board with this proposal, but there is it least one potential complication that seems worth bringing up.

Any Ur/Web code may encounter a benign exception requiring transaction restart. The canonical example is a serialization failure from optimistic SQL concurrency. Your suggestions above don't make it clear how transactions should be handled in general, including where to jump back to when a transaction needs restarting.

For simplicity's sake, what do you think of implementing the following two functions instead? 1) clone context but don't start a transaction for it (note that this also opens a database connection, checks the schema, and creates prepared statements!) 2) given a context and a URI, run the associated Ur/Web code in that context in a new transaction associated only with this operation

PS
By the way, I am missing the ability to pass Ur/Web records to/from
FFI. Is it hard to implement? I imagine they are represented with a
plain C structures in the transaction's memory pool so may it be that
it is not that hard?

C struct "subtyping" works nominally: two identically defined structs with different names are considered different types. Thus, one job of the Ur/Web compiler is to group together all uses of structurally equivalent record types, defining one C struct for each.

Because of this, it's hard to support _elegant_ use of Ur/Web records in C FFI code. You should be safe redefining the struct type with a different name and casting as necessary, though. This would require some changes to the Ur/Web compiler to allow things that it currently thinks are scary.

My main recommendation, though, is to do like this for a record that needs to cross the Ur-C boundary. This would be code in an FFI .urs file:
    type myrecord
    val myrecord : int -> string -> myrecord
    val getInt : myrecord -> int
    val getString : myrecord -> string


_______________________________________________
Ur mailing list
[email protected]
http://www.impredicative.com/cgi-bin/mailman/listinfo/ur

Reply via email to