[Ur] redirect breaks channels

Sergey Mironov grrwlf at gmail.com
Thu Dec 26 12:54:13 EST 2013


2013/12/25 Adam Chlipala <adamc at csail.mit.edu>:
> On 12/24/2013 07:24 PM, Sergey Mironov wrote:
>>
>> OK, I've looked under the hood and now I see that my application is
>> invalid because we can't call recv() on channels obtained from
>> anywhere but the channel call.
>
>
> Right.  Channels are page-view-specific, even though the type system isn't
> enforcing such use statically.
>
> I'm of two minds about your suggestion to introduce separate abstract types
> for writable and readable channels, where only the former is allowed in the
> database.  There's the clear "pro" of ruling out confused uses of channels,
> but there's the "con" of not allowing a pattern that's already used in one
> of the demos: what if we want to promote modularity by allowing code that
> checks if a channel has already been created for the current client?  If so,
> we can just return it out of the database, but such a handle becomes
> unreadable, with your typing change.

Yes, this additional use case requires storing read-end in the
database and this allows us to write non-working programs like my
program from previous letter. I think no simple typing changes would
help us here. Still, I think API should somehow highlight the fact
that channel is not an autonomous object, but a reference to a
client's slot. (according to the implementation, it is no more than a
tuple (channel_id,client_id)) Maybe, changing names would be enough
here. For me, recv associates with a function that could receive data
from any socket, which is not the case here. Another idea - add some
error-checking to the recv's code. It may raise an exception if user
passes it a channel which has client_id /= current_client_id.

>
> For now, I've just added another sentence to the manual, which should
> hopefully help guide new users sooner to the understanding that you have
> now.  We could still discuss potential code changes further.
>
>
>> Unfortunately, rewriting my program didn't help me to deal with errors
>> [1] . I see them in correctly written programs as well. Is it the
>> concurrency problem you mentioned in the manual? Could you please
>> explain in a bit more details why do we need to start a transaction
>> within a transaction here?
>>
>> [1] Begin error: cannot start a transaction within a
>> transaction<br/>Expunge blocked by error: Error running SQL BEGIN
>>
>
>
> Higher-order bits: I think this indicates an Ur/Web bug; it should not be
> possible to write Ur/Web code that does anything explicit with transactions.
> It's possible that something about the non-atomic transactions of SQLite
> (which I warn about in the manual) is responsible somehow, but it doesn't
> seem likely to me.
>
> I haven't been able to reproduce this issue.  Everything seems to work fine
> with your code with both SQLite and Postgres, after I change the redirect to
> return the proper page content inline instead.  Could you explain what
> changes you've made to the code you sent before and how you reproduce the
> error?
>
> I think I spotted some points in the Ur/Web implementation that could lead
> to behavior like this under some circumstances, and I've pushed a changeset
> to adjust them.

Maybe this bug shows itself only in some specific conditions. For
example, I'm using SSD drive so I have enabled 'no access time' option
for files and disabled the write cache.. don't know if it is
important. I've tracked the error message usign GDB, see the stack
trace below. The exact program text and .urp are in attach. Note, that
I have not applied your latest changes yet, will test them soon.

>
> P.S.: In general, your life using Ur/Web will be easiest if you stick to
> Postgres as the database.  The Ur/Web manual should contain literally a
> complete description of everything you need to know to set up Ur/Web and
> Postgres together, even if you have no prior knowledge of Postgres.

Yes, I never used Postgres before. But I am on my way of setting it up.


Regards,
Sergey

Stack trace:

Begin error: cannot start a transaction within a transaction<br
/>[Switching to Thread 0x7ffff5dd6700 (LWP 22275)]

Breakpoint 1, uw_error (ctx=ctx at entry=0x7fffe80008c0,
fk=fk at entry=BOUNDED_RETRY, fmt=fmt at entry=0x7ffff79d15c1 "Error running
SQL BEGIN") at urweb.c:692
692     __attribute__((noreturn)) void uw_error(uw_context ctx,
failure_kind fk, const char *fmt, ...) {
(gdb) bt
#0  uw_error (ctx=ctx at entry=0x7fffe80008c0, fk=fk at entry=BOUNDED_RETRY,
fmt=fmt at entry=0x7ffff79d15c1 "Error running SQL BEGIN") at urweb.c:692
#1  0x00007ffff79c7bc4 in uw_ensure_transaction (ctx=0x7fffe80008c0)
at urweb.c:783
#2  0x000000000040295b in __uwn_expunger_1404 (ctx=0x7fffe80008c0,
__uwr_cli_0=0) at /tmp/webapp.c:233
#3  0x00000000004039c5 in uw_expunger (ctx=0x7fffe80008c0, cli=0) at
/tmp/webapp.c:619
#4  0x00007ffff7bda932 in uw_do_expunge (ctx=0x7fffe80008c0, cli=0,
data=<optimized out>) at http.c:451
#5  0x00007ffff79c6963 in uw_expunge (ctx=0x7fffe80007c0,
ctx at entry=0x7fffe80008c0, cli=0, data=0x0) at urweb.c:3420
#6  0x00007ffff79cdae4 in uw_prune_clients (ctx=0x7fffe80008c0) at urweb.c:3450
#7  0x00007ffff79d0bb8 in client_pruner (data=<optimized out>) at request.c:594
#8  0x00007ffff6b91d7b in start_thread () from
/nix/store/6dqrci26svfasih50iabd6jxspwxjz7f-glibc-2.17/lib/libpthread.so.0
#9  0x00007ffff68c5ced in clone () from
/nix/store/6dqrci26svfasih50iabd6jxspwxjz7f-glibc-2.17/lib/libc.so.6
-------------- next part --------------
A non-text attachment was scrubbed...
Name: channel2.ur
Type: application/octet-stream
Size: 715 bytes
Desc: not available
URL: <http://www.impredicative.com/pipermail/ur/attachments/20131226/5be1ce63/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: channel2.urp
Type: application/octet-stream
Size: 129 bytes
Desc: not available
URL: <http://www.impredicative.com/pipermail/ur/attachments/20131226/5be1ce63/attachment-0001.obj>


More information about the Ur mailing list