I wanted to ask if someone else has yet tried to use Smalltalk YX for
web applications. Yesterday I wrote a quick and dirty code browser you
can see it at: http://dominicletz.de/cgi-bin/syx.
Maybe someone has already created something similiar (or better). I
really would like to know if syx supports continuiations so something
like the Seaside webserver could be run.
Dominic Letz
domini...@berlin.de
Hello,
this example is very very nice example, compliments.
I'm the author togheter with all you contributors, but really i never
tought to use syx for web.
This is the first example of a CGI app written in Syx.
Compliments again, i'm glad of this.
Actually, Syx itself is not complete as you can see neither the VM nor
classes. In fact i didn't spend so much time on both GUI and Web and other
external environments, therefore Syx doesn't support continuations and
other things or servers.
Anyway, for knowledge, can you public the code of that application, also
on the mailing list itself? I'm very courious to see what Syx can do at
this time and how it scales on stability and speed.
Thanks very much, bye.
--
http://lethalman.blogspot.com - Thoughts about computer technologies
http://code.google.com/p/syx - A new Smalltalk implementation
http://www.ammazzatecitutti.org - E adesso ammazzateci tutti
I have other questions because I wan't to add support for changing the
code and beauty the code.
1. How can I define class side messages?
2. How to add messages to already defined classes (from cold file or via
Smalltalk itself)?
3. How to update/change message source and recompile them?
4. What power do I have about the SYX threads or where to start reading
to understand them?
Here it comes.
Smalltalk Side: Dispatcher.st
Object subclass: #Dispatcher
instanceVariableNames: ''
classVariableNames: ''!
!Dispatcher methodsFor: 'as yet unclassified'!
run: queryString
| args classes inspect method |
'Content-Type: text/html' printNl.
'' printNl.
'<html><head><title>proto code browser</title></head><body>' printNl.
args := (queryString ifNil:['']) subStrings: '&'.
args do: [:each |
(each printString, '<br/>') printNl.
].
classes := Object allSubclasses.
args size = 0 ifFalse: [
inspect := Smalltalk at: (args at: 1) asSymbol.
(args size > 1) ifTrue: [
method := inspect methodDictionary at: (args at: 2) asSymbol.
]
].
'<table border="2" width="100%"><tr><td width="20%">' printNl.
classes do: [:each |
('<a href="?', each printString, '">', each printString, '</a><br/>')
printNl.
].
inspect = nil ifFalse: [
'<td valign="top"><table>' printNl.
inspect methodDictionary keysDo: [:key |
('<tr><td><a href="?', inspect printString, '&', key asString
printString, '">') printNl.
(key asString printString, '</td></tr>') printNl.
].
'</table><hr/>' printNl.
('Parent: <a href="?', inspect superclass printString, '">', inspect
superclass printString, '</a><br/>') printNl.
'Members:<br/>' printNl.
'<ul>' printNl.
inspect instanceVariableNames do: [:name |
('<li>', name printString, '</li>') printNl.
].
'</ul>' printNl.
'</td>' printNl.
].
method = nil ifFalse: [
'<td valign="top">' printNl.
('<pre>', method text, '</pre>') printNl.
'</table></td>' printNl.
]
'</td></tr></table>' printNl.
'<p><small>Mailme: dominic.letz AT berlin.de</small></p>' printNl.
'</body></html>' printNl.
! !
C++ Side main.cpp (there is no C++ feature but I'm used to create
C++ source files):
extern "C" {
#include <syx/syx.h>
}
#include <stdlib.h>
int main (int argc, char *argv[])
{
SyxOop instance;
SyxOop context;
SyxOop process;
//SyxOop result;
/* initialize Syx */
syx_init (argc, argv, NULL);
/* load the default image */
syx_memory_load_image (NULL);
// syx_memory_load_image ("default.sim");
/* now file in class and method declarations from our ST file */
syx_cold_file_in ("Dispatcher.st");
instance = syx_object_new(syx_globals_at("Dispatcher"));
/* create a MethodContext which sends the #with:and: message */
context = syx_send_binary_message(syx_nil, // the
parent context
instance, // the receiver
"run:", // the selector
syx_string_new(getenv("QUERY_STRING")));
/* now create a Process with that context */
process = syx_process_new (context);
/* execute the process in blocking mode */
syx_process_execute_blocking (process);
/* cleanup Syx */
syx_quit ();
return 0;
>
> Of course I can provide the sources but I must warn you they are dirty
> part of code :-) Ah and before i forget you can see the Smalltalk side
> of code also in the code browser itself...
>
I tried to search it but didn't find anything...
> I have other questions because I wan't to add support for changing the
> code and beauty the code.
> 1. How can I define class side messages?
> 2. How to add messages to already defined classes (from cold file or
> via Smalltalk itself)?
> 3. How to update/change message source and recompile them?
> 4. What power do I have about the SYX threads or where to start reading
> to understand them?
>
1) Like this:
!Dispatcher class methodsFor: 'test'!
Use class just after the class name
2) Maybe didn't understood, isn't it somewhat similar to problem 3?
3) Simply doing this:
MyClass methodDictionary at: #newMethod put: (MyClass compile: 'newMethod
.......')
4) Threads in Smalltalk are called Processes. There's not relationship
with OS-threads. Processes are like green-threads in Java. Start reading
ProcessorScheduler and Process.
About the code, it's very nice, i would like to suggest you some changes
next mail :)
Also, i would like to post it on my blog, can I? Obviously i'll mention
you as the author.
Thanks very much, you've done a very nice job.
Bye.
thank you for all your answers. Now I have to read more in the sources and
write some code.
- This link show the source of the dispatcher class (and its only method)
itself: http://dominicletz.de/cgi-bin/syx?Dispatcher&run:
- Yes, you can publish the code on your blog if you wish (although I think
the code) ugly.
Dominic
yes you can use the Code on your blog.
Thanks very much, let me know if you need anything else.
I'm going to release the new version, stay tuned :)
On 31 Ott, 20:21, "Dominic Letz" <dominic.l...@berlin.de> wrote:
> Hello Luca,
>
> thank you for all your answers. Now I have to read more in the sources and
> write some code.
>
> - This link show the source of the dispatcher class (and its only method)
> itself:http://dominicletz.de/cgi-bin/syx?Dispatcher&run:
>
> - Yes, you can publish the code on your blog if you wish (although I think
> the code) ugly.
>
> Dominic
>
> yes you can use the Code on your blog.
>
> Am 31.10.2007, 19:57 Uhr, schrieb Luca Bruno <lethalma...@gmail.com>:
>
>
>
> > In data 31 ottobre 2007 alle ore 18:26:52, dominic.l...@berlin.de
> > <dominic.l...@berlin.de> ha scritto:
in the meantime (last night) I also updated the sources a bit and added
sorting and html character escaping and reordered everything...
You can find the new sources now at the bottom line of:
http://dominicletz.de/cgi-bin/syx
On 1 Nov., 12:40, "dominic.l...@berlin.de" <dominic.l...@berlin.de>
wrote:
> Oh wow,
>
> in the meantime (last night) I also updated the sources a bit and added
> sorting and html character escaping and reordered everything...
> You can find the new sources now at the bottom line of: http://dominicletz.de/cgi-bin/syx
>
I suggest that maybe that would be nice to provide with the
distribution as a code example. If all work on this to make it better
it will be. ;-)
Thilo
I put it already in the examples dir of Syx with several changes to the
original ;)
I adapted parts of your code but had problems with "Smalltalk select: [:ea
| ea isClass]". It throws an Exception like: "Set does not understand
#isClass", so I stayed with "Object allSubclasses."
In the meantime I went another way and coupled the C and the Smalltalk
part even stronger. I replaced the cgi-interface with an
fastcgi(fcgi)-interface.
Cgi creates one new process per request. Fcgi in contrast creates only one
process which then processes all requests.
So the new "main.cpp" defines a request loop instead of just answering
only one request.
Excerpt from "main.cpp":
...
/* initialize Syx */
syx_init (argc, argv, NULL);
/* load the default image */
syx_memory_load_image (NULL);
/* now file in class and method declarations from our ST file */
syx_cold_file_in ("Dispatcher.st");
instance = syx_object_new(syx_globals_at("Dispatcher"));
while (FCGX_Accept(&in, &out, &err, &envp) >= 0) {
FCGX_PutS("Content-Type: text/html\r\n\r\n", out);
/* REQUEST LOOP */
}
...
This request loop brings two major advantages:
1. Decreased load time. For all requests only the request loop is executed
by an already running process this means:
- No fork()/process creation overhead
- No library loading time (libsyx.so)
- No image loading time
- No cold file parsing time
=> Request take now around 300ms
2. State. Every request is answered by the same image in the very same
state.
- Variables stay when changed from request to request.
=> I added a request counter in the dispatcher class which is visible at
bottom of the page
I keep working on it..
-Dominic
You've to use the latest SVN as i said. Good work.
Cool for fast-cgi :) nice example
Bye.