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. I agree, that otherwise we would provoke a security weakness. But also it means that channel API signatures (in basis.urs) do not describe the server-side implementation correctly. I would suggest writing something like
con channel :: Type -> Type con channelw :: Type -> Type (* the write end of a channel *) val channel : t ::: Type -> transaction (channel t) val channelw : t ::: Type -> channel t -> channelw t val send : t ::: Type -> channelw t -> t -> transaction unit val recv : t ::: Type -> channel t -> transaction t and define sqlifiers for 'channelw' but not for 'channel' to forbid calling recv on anything but the valid channel. Maybe it is possible to do with minimal changes in C code. 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 Regards, Sergey 2013/12/25 Sergey Mironov <[email protected]>: > Hi. > I've faced a channel issue. Looks like I can't put a value into a > channel from the transaction which didn't create that channel using > `channel' function. Consider the following program: > > table t : { Id : int , Chan : channel int } > > fun put (i:int) = > r <- oneRow1(SELECT * FROM t WHERE t.Id = 0); > Basis.send r.Chan i > > fun monitor {} : transaction page = > r <- oneRow1(SELECT * FROM t WHERE t.Id = 0); > ch <- return r.Chan; > let > fun ping () = > i <- recv ch; > alert (show i); > ping () > in > return > <xml> > <body onload={ping ()}> > <button value="Send a value" onclick={fn x => rpc (put 33)}/> > </body> > </xml> > end > > fun main () : transaction page = > ch <- channel; > dml(INSERT INTO t (Id,Chan) VALUES (0,{[ch]})); > redirect (url (monitor ())) > > > The monitor here doesn't receive any messages from the channel, > despite the fact that there is only one channel in the database. But > if I move > ch <- channel; dml(INSERT INTO t (Id,Chan) VALUES (0,{[ch]})); > lines from main to the monitor's body, everything works. Please > suggest a fix/workaround! > > Merry christmas to all > > Sergey > > PS > > Application reports > Begin error: cannot start a transaction within a transaction<br > />Expunge blocked by error: Error running SQL BEGIN > Note, I'm using sqlite engine. I've tried it using vanilla urweb too:) > The source is in attach. _______________________________________________ Ur mailing list [email protected] http://www.impredicative.com/cgi-bin/mailman/listinfo/ur
