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