class WSequence
{
static const AtomicInt currentValue := AtomicInt()
static Int next()
{
return currentValue.getAndIncrement()
}
}
This is too strange for me.
brianSun 23 May 2010
No need to do anything complicated like use AtomicRef. You can use the same sort of design you might use in Java:
const class Foo
{
const static Foo instance := make()
private new make() { ... }
}
However since a singleton is by definition shared between all threads, then it must be immutable to guarantee thread safety (as all static fields must be).
If you singleton is not immutable, then you must make it an actor.
pavel_repinSun 23 May 2010
Ok. I done as you say.
I try to develop web application in maner desktop gui application. In my program for each client session I create gui application that can rendered into html. User can iteract with application that associated with his session and change application's state.
I need not immutable singleton and make an Actor in two versions.
In first version I store applications in an Actor and return application for current session in Future as serializable object. This is bad solution because application encoded and decoded twice on each request. First time when request get current application and second time after application handle request and her state was changed.
In second version I store applications in an Actor also. But I handle request in this Actor thread. This solution solve problems with serialization but all request will be processed in one thread. That's bad.
In general you won't wrap up WispService inside another actor. Rather your server's boot script will just launch one or more configured services. For example:
// launch server
MyAppService { }.start
WispService { it.port = port }.start
In this case instead of a singleton, you probably want to create your application as a service (or maybe just a WebMod). Then you can lookup:
MyAppService service := Service.find(MyAppService#)
Your service would probably use actors under the covers. If you can try to make your actor messages const which makes them super efficient. But if you have to serialize your messages it should still be pretty performant.
Maybe you can explain your application a bit more at the high level.
pavel_repinSun 23 May 2010
Thank you for your interest and help, Brian
My project have two pods: hello.pod - demo hello world app and webtoolkit.pod - web library similar to http://www.webtoolkit.eu/wt but very simplify.
hello.pod classes:
using util
using webtoolkit
class Hello : AbstractMain
{
@Opt { help = "port" }
Int port := 8080
override Int run()
{
WServer server := WServer( HelloAppFactory(), port )
runServices( [ server.service ] )
return 0
}
}
using webtoolkit
@Serializable
class HelloAppFactory : WAppFactory
{
override WApp create()
{
return HelloApp()
}
}
using webtoolkit
class HelloApp : WApp
{
private WLineEdit nameEdit
private WText greetingText
private WTable friendsTable
new make()
{
this.title = "Hello world" // application title
this.root.addWidget( WText("Input friend name, please ? ") ) // show some text
this.nameEdit = WLineEdit( "", this.root ) // allow text input
WPushButton b := WPushButton( "Great friend", root ) // create a button
b.setMargin( [10:WSide.left] ) // add 10 pixels margin
this.root.addWidget( WBreak() ) // insert a line break
this.greetingText = WText( "", root ) // empty text
this.root.addWidget( WHeader("Greated friend's list") ) // show some header
this.friendsTable = WTable( root ) // empty table
this.friendsTable.setHeaders( [ WText("Friend's name") ] )
|->| greating := |->|
{
Str name := this.nameEdit.text.trim
if( name.isEmpty )
this.greetingText.text = "You don't input friend's name"
else
{
this.greetingText.text = "Hello there, " + name
this.friendsTable.addRow( [ WText( name ) ] )
}
}
b.clicked = greating
nameEdit.enterPressed = greating
}
}
I think that this code explain more.
Webtoolkit.pod main classes:
const class WServer
{
const WispService service
new make( WAppFactory appFactory, Int port := 8080 )
{
WRequestHandler.instance.send( appFactory )
this.service = WispService()
{
it.port = port
it.root = WWebMod()
}
}
}
class WApp
{
Int id := WSequence.next
Str? sessionID
Str title := "webtoolkit"
Str onLoad := ""
WWidgetContainer root := WWidgetContainer()
Void setSessionID( Str sessionID )
{
this.sessionID = sessionID
}
Str handleRequest( WReq req )
{
WLog.info( "handle request by app with ID = $id" )
// process actions
if( req.params != null )
{
req.params.each |Str value, Str key|
{
WLog.info( "param: '$key'->'$value'" )
Str[] actionAndID := key.split('_')
WLog.info( "actionAndID: '$actionAndID'" )
Str action := actionAndID.get(0)
Int id := actionAndID.get(1).toInt
WWidget? widget := root.find( id )
if( widget != null )
widget.action( action, value )
}
}
// render html
Str html := "<HTML><HEAD><TITLE>$title</TITLE></HEAD><BODY>"
html += root.render
html += "</BODY></HTML>"
return html
}
}
Sorry for size of this post. I think sources explain itself better. It's my first fan's project. If you'll see my mistakes in undestanding of fan tell me, please.
brianSun 23 May 2010
My first thought looking at all that code, is that is sort of reminiscent of the pain that Java developers go thru to abstract their design. So I would pose this question - what is the absolute simplest way to write your code in the least number of lines?
There seems like there are two basic concepts:
a simple "framework" class which is used to build widget trees and route action requests
an actual page built up of widgets
Unless there is truly some value in the other classes and abstractions, I would try to simplify the design into a single WebMod or Weblet class that handles the framework side of things.
You might want to take a look at the old Fantom Widget code which was the original webapp pod.
pavel_repinMon 24 May 2010
Thank you for links. I see a few useful techniques. But concept is not usual for me. Need time to change my way of thinking.
pavel_repin Fri 21 May 2010
I can't find answer on this question. How possible implement singleton pattern?
I try to use Atomic reference. But reference don't work also:
But I can implement singleton Sequence:
This is too strange for me.
brian Sun 23 May 2010
No need to do anything complicated like use AtomicRef. You can use the same sort of design you might use in Java:
However since a singleton is by definition shared between all threads, then it must be immutable to guarantee thread safety (as all static fields must be).
If you singleton is not immutable, then you must make it an actor.
pavel_repin Sun 23 May 2010
Ok. I done as you say.
I try to develop web application in maner desktop gui application. In my program for each client session I create gui application that can rendered into html. User can iteract with application that associated with his session and change application's state.
I need not immutable singleton and make an Actor in two versions.
In first version I store applications in an Actor and return application for current session in Future as serializable object. This is bad solution because application encoded and decoded twice on each request. First time when request get current application and second time after application handle request and her state was changed.
In second version I store applications in an Actor also. But I handle request in this Actor thread. This solution solve problems with serialization but all request will be processed in one thread. That's bad.
Can you help me to improve this program?
brian Sun 23 May 2010
In general you won't wrap up WispService inside another actor. Rather your server's boot script will just launch one or more configured services. For example:
In this case instead of a singleton, you probably want to create your application as a service (or maybe just a WebMod). Then you can lookup:
Your service would probably use actors under the covers. If you can try to make your actor messages const which makes them super efficient. But if you have to serialize your messages it should still be pretty performant.
Maybe you can explain your application a bit more at the high level.
pavel_repin Sun 23 May 2010
Thank you for your interest and help, Brian
My project have two pods: hello.pod - demo hello world app and webtoolkit.pod - web library similar to http://www.webtoolkit.eu/wt but very simplify.
hello.pod classes:
I think that this code explain more.
Webtoolkit.pod main classes:
Sorry for size of this post. I think sources explain itself better. It's my first fan's project. If you'll see my mistakes in undestanding of fan tell me, please.
brian Sun 23 May 2010
My first thought looking at all that code, is that is sort of reminiscent of the pain that Java developers go thru to abstract their design. So I would pose this question - what is the absolute simplest way to write your code in the least number of lines?
There seems like there are two basic concepts:
Unless there is truly some value in the other classes and abstractions, I would try to simplify the design into a single WebMod or Weblet class that handles the framework side of things.
You might want to take a look at the old Fantom Widget code which was the original webapp pod.
pavel_repin Mon 24 May 2010
Thank you for links. I see a few useful techniques. But concept is not usual for me. Need time to change my way of thinking.