r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[!Cheyenne] Discussions about the Cheyenne Web Server

Dockimbel
19-Nov-2011
[10901x3]
In the next days, I will spend a day or two on Cheyenne, to fix a 
few pending issues (like the broken websocket compatibility after 
latest RFC changes).
If you need it, I should be able to add it easily.
If you think there's a more general solution to this use-case, let 
me know.
Janko
19-Nov-2011
[10904x3]
This was my old code because ot it (I check for </html> and </form> 
to see if I signed out) . Now I am making it status for validation 
for example it will be status 403, etc ..


    onChange2: function(rq, pars) {
        this.assureLANG();
        if (rq.readyState == 4) {
            if (rq.responseText) {
                if ( rq.responseText.indexOf('</html>') > 0 ) {

                    if ( rq.responseText.indexOf('</form>') > 0 ) {
                        alert(LANG.err.session_exp);

                        window.location = window.location.href.replace(/#.*/g, "")+"";
                    } else {
                        alert(LANG.err.ajax_err);
                    }
                } else {
                    c(r.responseText);
                }
            } else { this.onError(); }
        }
    },
--

You really don't have to change it now .. you can add this any time 
later when it maybe clears out even better .. I don't want to keep 
you from RED
Cheyenne was serving me well for all this time and this is no real 
issue .. just a notice for future maybe
Dockimbel
19-Nov-2011
[10907x3]
Well, the biggest task is getting websockets up again, modifying 
AUTH should really be a matter of a few lines of code.
I also need to review PHP support as I will make a Cheyenne presentation 
next week at a big PHP meeting here.
So, I will spend at least a day on it.
Janko
19-Nov-2011
[10910x4]
I quickly mocked up how ajax code would look if you made it return 
401

    onChange2: function(rq, pars) {
        this.assureLANG();
        if (rq.readyState == 4) {
            if (rq.status == 401) {
                alert(LANG.err.session_exp);

                window.location = window.location.href.replace(/#.*/g, "")+"";
            } else if (rq.status = 200) {
                success(r.responseText);
            } else if (rq.status == 403) {
                validation(r.responseText);
            } else {
                this.onError();
            }
        }
    },
well .. you decide .. for me it's not a problem, really .. and I 
am also starting to think about HTTP codes now so I don't have the 
clearest view yet
hm.. same would be then for error, again when in JSON mode .. instead 
of html explanation you should return 500
but yes, the question is what is the best way to determine the JSON 
mode (or XML or CSV or ...)
Dockimbel
19-Nov-2011
[10914]
Precisely. :-)
Janko
19-Nov-2011
[10915]
I will have a lot more experiences about this in few months because 
I am just working on this stuff regarding the API and export. I used 
aditional get param so user can select what format she wants. But 
I was educated by this guy that I should look at Accept headers, 
which I ignored happily ..:) .. same about statuses which I didn't 
use. Now I am getting home at this, so we can talk in a while and 
determine the most systematic and clean way for this. And such that 
will make the REST purists happy
Dockimbel
19-Nov-2011
[10916]
I'm looking forward to it!
Janko
19-Nov-2011
[10917]
Ok, great.. I will get by when time comes
Dockimbel
19-Nov-2011
[10918]
I think that Gabriele could also have some good inputs on the best 
practices to support, as he's doing a lot of AJAX programming.
Janko
19-Nov-2011
[10919]
great
Dockimbel
20-Nov-2011
[10920x3]
My main server is down since a few hours due to a non-technical issue. 
This affects all the following web sites:
- cheyenne-server.org
- curecode.org
- part of red-lang.org


The problem should be solved in an hour. This server is still owned 
by my former company, Softinnov, who forgot to do the renewal in 
time.
Ok, server is up again, issue solved.
Too bad I thought it was a hardware issue and I sent a reboot from 
the control panel, just a few seconds before realizing that the server 
plan has expired. The server was running since 670 days uninterrupted.
Janko
23-Nov-2011
[10923]
I want to log certain events from the webapp. What would be the most 
efficient way to do this (by this I mean one that would have least 
impact on server responsivenes). I would like to use something silimar 
to debug/probe debug/print .. Is it possible to have use the existing 
loging functionality to log custom stuff to custom log? (or is this 
just normal file append)?
Endo
23-Nov-2011
[10924]
I think its ok to use append if its not a heavy-loaded web site. 

I did this to prevent possible file access problem if it happens 
same time in very rare cases:

		unless 'ok = loop 3 [
			if not error? try [
				save voter-file append voters session/content/username
			] [
				break/return 'ok
			]
			wait 0:0:0.1
		] [
			response/redirect "error.rsp?code=error-on-voting"
		]
Dockimbel
23-Nov-2011
[10925]
You can use debug/* logging functions, but they will only log in 
%trace.log file. Writing directly to a log file from RSP script is 
unsafe (unless you take great care about concurrent accesses). So, 
if you want to have custom logs from RSP scripts, you should use 
the OS syslog service for a really realiable solution. The debug/* 
log functions use their own solution for serializing disk writes, 
they are passing data to Cheyenne main process that does the writings 
to disk.
Kaj
23-Nov-2011
[10926]
You could also make your own syslog server with 0MQ and send log 
messages to it from RSP scripts. That will offload the writing to 
a different process and 0MQ will take care of serialisation
Janko
23-Nov-2011
[10927]
Endo, thanks for the code. I will need something similar for sqlite. 
I just got a first db is locked error yesterday with it at UsrJoy.


What I'm trying to log is side-info (like usage info) so I don't 
want to inpact the speed of response by having aditional disk write 
in the request-response process (it has to be async).


Doc: I used debug functions for various info logging too now (and 
I do diff on trace in cron and send myself email if there is any 
difference), but I am trying to log more things and I would like 
to leave trace.log for errors only. I was interested if the existing 
functionality that serializes debug to trace.log could be used to 
log to some other file. like info.log . That would complicate the 
app-code the least.. otherwise I was thinking of what  Kaj  proposed, 
to have some queue to send data over via tcp to and it will write 
it to disk in intervals. That would bring another dependancy into 
app-code.. something like redis could automatically work like this 
I think.
Dockimbel
23-Nov-2011
[10928x2]
It could be possible to extend debug object to handle an /info refinement 
that would log to an %info.log file, but that would put some burden 
on Cheyenne main process when in production. I thought about writing 
an OS logging service wrapper, but never found the time for that. 
I usually do all my writings from webapps into databases that are 
able to handle concurrent accesses reliably (so, not sqlite).
The probably best option would be for Cheyenne to spawn a new process 
that would handle all the log files serialization (both for Cheyenne 
internal use and for web apps). The code for that is already bundled 
in Cheyenne main process, so it would not be a big work to extract 
it and spawn a new process. (but would require at least a couple 
of days, including testing).
Kaj
23-Nov-2011
[10930]
0MQ is already heavily async, and you can make the request/response 
pattern not wait
Dockimbel
23-Nov-2011
[10931x2]
Btw, I am currently working on making Cheyenne websocket support 
conform to the latest RFC specification. The current Cheyenne support 
is obsolete and won't work anymore with latest browsers.
The newer websocket RFC is much better written and more exhaustive 
than the previous versions. The protocol has also nicely improved 
fixing the remaining security issues.
Kaj
23-Nov-2011
[10933x2]
That's very welcome
I thought SQLite supports concurrent access. Isn't that so?
Dockimbel
23-Nov-2011
[10935]
SQLite use to have issues handling concurrent writes (data corruption 
could happen), I don't know if recent versions improved that or not.
Kaj
23-Nov-2011
[10936x2]
Judging by the documentation it should be able to do it, but I admit 
I usually mistrust such things
It makes heavy requirements on the file locking of the operating 
system for that, and it does have a document section that explains 
how operating systems are buggy and badly documented, so that doesn't 
exactly instill confidence
Dockimbel
23-Nov-2011
[10938x3]
Reliable and efficient file locking is hard to achieve, I agree with 
that. That's why I went for a syslog-like solution for Cheyenne.
http://www.sqlite.org/faq.html#q5


Multiple processes can have the same database open at the same time. 
Multiple processes can be doing a SELECT at the same time. But only 
one process can be making changes to the database at any moment in 
time, however.
When any process wants to write, it must lock the entire database 
file for the duration of its update


However, client/server database engines (such as PostgreSQL, MySQL, 
or Oracle) usually support a higher level of concurrency and allow 
multiple processes to be writing to the same database at the same 
time. This is possible in a client/server database because there 
is always a single well-controlled server process available to coordinate 
access. If your application has a need for a lot of concurrency, 
then you should consider using a client/server database.
Pekr
23-Nov-2011
[10941x2]
Sounds good, no?
Those locks last only a fraction of time imo. Shouldn't it be good 
for small stuff?
Dockimbel
23-Nov-2011
[10943]
Small stuff: probably, but if you ever need to scale up, better start 
right from the beginning.
Dockimbel
24-Nov-2011
[10944]
Bad news for websocket support in REBOL: the new RFC requires that 
client encodes data sent to server using a basic XOR encryption algorithm:


http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10#section-4.3


This is a bad news for us, because it requires to process all bytes 
received, one by one to decode the message. REBOL is very slow at 
processing big data in loops, so the overhead can be very significant 
for data frames of a few dozen KB and more. It could affect Cheyenne 
global performances drastically.


However, it could have been worse, this encryption scheme is not 
required for data sent by server. So, as long as clients are sending 
small messages (up to a few KB), the overhead should be low. Fortunately, 
the usual client messages are queries to obtain data, so usually 
small. But if you have to move big amouts of data (like XML documents) 
back and forth through websockets, Cheyenne won't be able to cop 
with the load and it will most probably be a show-stopper.
Geomol
24-Nov-2011
[10945]
Can it be solved by calling a routine from a dynamic linked library?
Dockimbel
24-Nov-2011
[10946x2]
Yes, but in Cheyenne context, having to maintain a cross-platform 
C lib to that would be really annoying. It would be the end of Cheyenne 
as a one-file server. Also, it wouldn't run on Core anymore.
to that
 = "for that"
Geomol
24-Nov-2011
[10948]
Make the C lib open source and let people, who want that functionality, 
maintain the lib. It shouldn't necessarily be your job.
Dockimbel
24-Nov-2011
[10949x2]
In the end, the burden will fall on my shoulders if I want fixes 
and updates to be done in time (as usual). If someone makes such 
lib (just 3 lines of C, btw), maintains it (means provide binaries 
for target platforms), I can add an optional loader in Cheyenne to 
use it when present. As for myself, I prefer to switch to Red asap.
I have pushed a preliminary implementation of the latest websocket 
RFC to Cheyenne SVN repo. It works only for text messages of size 
< 126 bytes. I will get back to it in the next day and complete it.