The folks at Sencha have long used their project and api documentation as a technology demonstration; the javascript they apply admits no graceful degradation, harming searchability, the reading capability of the disabled and usability. Especially agrivating in the ExtJS3 series documentation are the pseudo-tabs: clicking a “link” in the API will spawn a new “tab” inside of the documentation/application which do not persist across reloads and/or the space of about 30 minutes. The new ExtJS4 series has seemingly improved somewhat, but not much. Clicking a link in the documentation sends me to the requested resource, sure, but I get chucked randomly down the page. Scrolling focus has been overloaded and replaced—now not only must I have focus in my browser window—which I’m used to—but I have to have focus in their sub-window, with no visual clue other than my own mouse pointer straying too close to some visually ill-defined pseudo-scrollbar.
The project that I’m on dictates the use of ExtJS, but this seems crazy. And, you know, the Sencha team does things that I find really goofy but almost any and all web-dev application work I’ve had contact with feels something like this: cobbled together, non-deterministically functional and astoundingly difficult to get right.
Blech.
(Incidentally, using Chromium 12.0.742.100 I get chucked to the end of the above link. Firefox 4.0.1 is okay. Write once, test everywhere on every version?)
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0xb6d33b7d, pid=949, tid=2831403888
#
# JRE version: 6.0_25-b06
# Java VM: Java HotSpot(TM) Server VM (20.0-b11 mixed mode linux-x86 )
# Problematic frame:
# V [libjvm.so+0x2b0b7d] pthread_attr_init+0x2b0b7d
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
--------------- T H R E A D ---------------
Current thread (0x09a72800): VMThread [stack: 0xa8bbc000,0xa8c3d000] [id=954]
siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x00000050
Registers:
EAX=0x00000000, EBX=0xb0cf4058, ECX=0x00000000, EDX=0xb19f5ba8
ESP=0xa8c3ba20, EBP=0xa8c3ba88, ESI=0xb19f5bb0, EDI=0xb0cd8540
EIP=0xb6d33b7d, EFLAGS=0x00010246, CR2=0x00000050
Top of Stack: (sp=0xa8c3ba20)
0xa8c3ba20: b19f5bb0 b0cf4058 00000000 00000000
0xa8c3ba30: a8c3ba60 a8c3ba40 00000001 0000006c
0xa8c3ba40: b726e5d8 b0cf4054 a8c3ba88 b37cfeb8
0xa8c3ba50: b7274fb0 01400000 b728df20 b7171f00
0xa8c3ba60: b3010100 00000000 00000000 00000001
0xa8c3ba70: b37cfeb8 b2be1400 00000000 099f2750
0xa8c3ba80: 099b5f50 a8c3bae0 a8c3baa8 b6e0ef0c
0xa8c3ba90: 099f2750 a8c3bae0 a8c3bb48 b6e04276
Instructions: (pc=0xb6d33b7d)
0xb6d33b5d: 40 5c 89 45 e4 8b 45 e4 89 02 8b 45 b4 8d 1c 83
0xb6d33b6d: e9 de fe ff ff 85 c0 78 14 50 50 8b 42 08 53 56
0xb6d33b7d: ff 50 50 89 c1 83 c4 10 e9 3c ff ff ff 89 c2 8b
0xb6d33b8d: 7b 08 c1 f8 10 83 e2 3f 88 d1 25 ff 00 00 00 d3
Register to memory mapping:
EAX=0x00000000 is an unknown value
EBX=
Well, these are rare…
I’m always a little nervous when the lines of code go up as a part of a trend. Presumably better abstractions will reduce the bulk of a project, but the intrinsic difficulty of a thing cannot be removed or ever completely hidden away behind careful encodings.
Moreover, what do I have against 6 AM?
ex gitstats
Luciano,
I’m relatively new to Akka, but I’ve been designing and building systems in Erlang for years. If I might speak a bit toward the architecture of actor based servers:
On Thu, May 5, 2011 at 6:02 PM, Luciano Fiandesio
Hi Patrik, I have been reading past posts on this mailing list about pooling and load balancing of actors and I’m uncertain about the best practices here.
Given the scenario where multiple remote typed actors of the same type have to process incoming messages in parallel (and execute blocking and potentially time consuming operations), I understand I have the following options:
- use an Untyped Dispatcher or Load balancer (http://doc.akka.io/ routing-java)
- create an actor per message, and set the maximum number of actors running at the same time (not sure how to do that using the Java API)
Which approach you take a largely a matter of need, but, in general, actors are to be considered as having remarkably little overhead: you may make millions at a time without trouble. Whereas thread-per-connection servers are limited in their ability to scale, actor-per-connection servers are not. If you can encapsulate a bit of workflow as a concurrent activity create an actor that performs that work. In some instances your workers will be long-lived—because the work is infinite—and in others short—because the work is finite.
I imagine that you are a morally right and ethically straight man, that you do not hang about with the dregs of humanity: let me tell you about 4chan. It’s a collection of named message boards, each board having threads where users can make posts in a flat hierarchy, sharing images and racial insults. The threads are temporary—they’re maximum lifetime fluctuates, but they last no more than a day. Further, boards have a bounded capacity, they act like LRU caches: threads that see no active posting in a busy board are eventually terminated. The hierarchy looks something like this:
4chan
|-- r9k
| |-- against_dog
| `-- against_god
|-- a
| `-- anime_millhouse
|-- b
| |-- queen_boxxy
| `-- the_game
`-- s
`-- moar
At the top we find ‘4chan’. This is the application supervisor and runs infinitely. The entities in the set {r9k,a,b,s} are the boards and are the children of 4chan. At boot time, 4chan creates its children in a 0neForOne arrangement, restarting them as required. The boards, too, are infinite supervisors: their children are the temporary threads. The board threads are created dynamically in response to user inputs—when they die (either due to reaching the end of their lifetime or because of a bug) the board thread does not restart the actor. Each board thread manages its own state and lifecycle—likely by exposing a Jetty resource for REST operations. User input validation, captcha verification, tri-force rendering and so on are all managed solely by a single board thread actor instance: only at creation and forced destruction does a board ever interact with its thread.
Being that we are modeling 4chan, the boards must create only a limited number of threads. Internal to each board actor, maintain an LRU cache. For each NewThread event—achieved by having the board act as a Jetty resource or by tethering a slave Jetty actor to the board actor—simply create a new thread actor, place it in the LRU cache and feed PoisonPill to any thread which falls out of the LRU. Board thread timeouts may be achieved by forming the thread as an FSM with an internal self-destruct state reached eventually by careful timeInterval delays. If the number of board threads may be unbounded, abandon the internal LRU cache and trust only to thread self-destruction.
If we assume that each 4chan board thread must make an entry in an FBI database for each poster’s IP address—and that this takes a non-trivial amount of time—we can easily maintain performance by doing the following:
- Create a new ‘snitch’ actor for each post.
- Sending a message with the IP payload from the board to the snitch.
- The snitch performs the long write to the FBI database.
- Job done, the snitch kills itself.
You’ll note, we might potentially make an unbounded number of snitches. If that’s a problem, keep a simple counter: increment on snitch creation, decrement on destruction. It is best to assume, however, that you don’t need such management: the actor style—at least as espoused in the Erlang community—is to do the simplest thing which will work, only complicating the solution once you have shown that a loaded system has scaling issues. Actors are a cheap resource: make as many as you want. Pools of actors are a hold-over from thread-based system design than from actor-based systems.
Until, of course, you need one.
- create a number of typed actors and link them to a supervisor actor that uses work stealing dispatcher (again, not sure how to do that).
Are the options exhaustive? Which is the recommended approach, considering that the actors will execute blocking operations?
I would suggest that you create one actor per concurrent block of operations, watched by a OneForOne supervisor. If an individual child dies, save off the actor’s initial state—you can do that in Akka, right?—and restart the concurrent block of operations in a new actor.