I couldn't wait and sketched a patch illustrating the idea. https://raw.github.com/grwlf/urweb-callback/master/1_of_1__Draft__loopback_request_for_internal_http_server.patch https://raw.github.com/grwlf/urweb-callback/master/Test.ur (a test)
It's for internal http server only, and it is 'quick and dirty' so I'm just asking for review and discussion of the potential problems. Here are few I already see there: - the mimic_request function may run out of stack space if recursion happens. should I enqueue such requests it in a separate thread? - mimic_request starts new database transaction while running in the context of a previous one. is it deadlock-free? - minimal test works (prints debug message), but server reports "Database connection initialized" every time mimic_request is called. why is that? 2013/12/16 Sergey Mironov <[email protected]>: > I just remember that it's not always possible to query server > port/host because application may use external web server or proxy, so > it is not always possible to visit callback url. What I actually want > is to mimic page request from inside the server without actually > opening HTTP session, parsing headers, etc. I guess it is not that > simple currently. Correct me if I'm wrong.. > > 2013/12/16 Sergey Mironov <[email protected]>: >> Hi. I'd like to re-open the topic [1] regarding UrWeb callbacks from C >> code. Imagine the 'anonymous downloader' application, where >> 1. user logs in and enters the link to download >> 2. server starts the download task, task runs for hours >> 3. server sends an email to user when the download finishes >> >> Also, imagine that I have two separate UrWeb,library: one for starting >> downloader threads and one for sending emails. I'd like to glue them >> together but in order to do so I have to provide the thread with a >> callback to call UrWeb handler which eventually calls email sender. >> AFAIK, there is no pre-designed way callback an UrWeb code, so here >> are my ideas and questions: >> >> 1) >> A simple solution I see is to provide the downloader with an url to >> trigger completion actions. the code may looks like >> >> fun handler (clientId: int) = >> email <- queryEmail clientId; >> Emailer.sendTo email "Download completed" >> >> fun download (u:string) = do >> clientId <- newClient; >> runThreadWithCallback ("wget " ^ u) (url (handler clientId)) >> >> Looks like no problems here except a low-level one: C FFI code needs >> to know not url alone but also the current hostname (127.0.0.1 may >> work) and the port the server is running on. Is there a safe way to >> query this information from the runtime? >> >> 2) >> A cool solution: Invent some kind of 'detached thread monad'. the new >> code would be like >> >> fun handler (clientId: int) = >> email <- queryEmail clientId; >> Emailer.sendTo email "Download completed" >> >> fun download (u:string) = do >> clientId <- newClient; >> runInSeparateThread (fn thread_id => >> u <- execute ("wget " ^ u); >> (* other logic in Ur/Web language *) >> visit (url (handler clientId)) >> ) >> >> where >> >> val execute : string -> detached_transaction int >> val visit: url -> detached_transaction unit >> >> are both FFI functions declared in detached_transaction monad. But >> AFAIK only `transaction' or pure functions are allowed for C FFI.. And >> worse, this snippet would require runInSeparateThread to call pure >> anonymous Ur/Web function. So we have to >> a) allow arbitrary monads in C FFI code >> b) add support for native [val runInSeparateThread : (int -> >> detached_transaction unit) -> transaction unit] I think this would >> be awesome, is it hard to implement? >> >> Regards, >> Sergey >> >> [1] - http://www.impredicative.com/pipermail/ur/2012-September/001227.html _______________________________________________ Ur mailing list [email protected] http://www.impredicative.com/cgi-bin/mailman/listinfo/ur
