Swapped out Scala Actors to a reactor based impl (still restart and linking to do) + finalized transactional persisted cassandra based vector (ref to go)

This commit is contained in:
Jonas Boner 2009-06-10 20:04:33 +02:00
parent 167b724671
commit ac52556595
22 changed files with 726 additions and 404 deletions

554
akka.iws
View file

@ -2,14 +2,25 @@
<project relativePaths="false" version="4"> <project relativePaths="false" version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" name="Default" comment="&#10;# Brief commit desciption here&#10;&#10;# Full commit description here (comment lines starting with '#' will not be included)&#10;&#10;"> <list default="true" name="Default" comment="&#10;# Brief commit desciption here&#10;&#10;# Full commit description here (comment lines starting with '#' will not be included)&#10;&#10;">
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java" afterPath="$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/test/scala/ActorTest.scala" afterPath="$PROJECT_DIR$/kernel/src/test/scala/ActorTest.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemStateful.java" afterPath="$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemStateful.java" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/Kernel.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/Kernel.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/reactor/Future.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/reactor/Future.scala" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/reactor/EventBasedDispatcher.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/reactor/EventBasedDispatcher.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/Transaction.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/Transaction.scala" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/ActiveObjectGuiceConfiguratorTest.java" afterPath="$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/ActiveObjectGuiceConfiguratorTest.java" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/ActiveObject.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/ActiveObject.scala" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/ActiveObject.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/ActiveObject.scala" />
<change type="DELETED" beforePath="$PROJECT_DIR$/kernel/src/main/scala/reactor/EventDrivenDispatcher.scala" afterPath="" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/Transaction.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/Transaction.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/ResultOrFailure.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/ResultOrFailure.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/test/scala/ThreadBasedDispatcherTest.scala" afterPath="$PROJECT_DIR$/kernel/src/test/scala/ThreadBasedDispatcherTest.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/akka.iws" afterPath="$PROJECT_DIR$/akka.iws" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/akka.iws" afterPath="$PROJECT_DIR$/akka.iws" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/test/scala/EventBasedDispatcherTest.scala" afterPath="$PROJECT_DIR$/kernel/src/test/scala/EventBasedDispatcherTest.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/reactor/ThreadBasedDispatcher.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/reactor/ThreadBasedDispatcher.scala" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/reactor/ThreadBasedDispatcher.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/reactor/ThreadBasedDispatcher.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/PersistentStateTest.java" afterPath="$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/PersistentStateTest.java" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/CassandraNode.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/CassandraNode.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/Actor.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/Actor.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/reactor/Future.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/reactor/Future.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/PersistentStateful.java" afterPath="$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/PersistentStateful.java" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/State.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/State.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/DataFlowVariable.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/DataFlowVariable.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/Logging.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/Logging.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/reactor/Reactor.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/reactor/Reactor.scala" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/reactor/Reactor.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/reactor/Reactor.scala" />
</list> </list>
<ignored path="akka.iws" /> <ignored path="akka.iws" />
@ -30,59 +41,7 @@
</component> </component>
<component name="DebuggerManager"> <component name="DebuggerManager">
<line_breakpoints> <line_breakpoints>
<breakpoint url="file://$PROJECT_DIR$/kernel/src/main/scala/State.scala" line="152" class="Class at State.scala:152" package=""> <breakpoint url="file://$PROJECT_DIR$/kernel/src/main/scala/ActiveObject.scala" line="142" class="Class at ActiveObject.scala:141" package="">
<option name="ENABLED" value="true" />
<option name="LOG_ENABLED" value="false" />
<option name="LOG_EXPRESSION_ENABLED" value="false" />
<option name="SUSPEND_POLICY" value="SuspendAll" />
<option name="COUNT_FILTER_ENABLED" value="false" />
<option name="COUNT_FILTER" value="0" />
<option name="CONDITION_ENABLED" value="false" />
<option name="CLASS_FILTERS_ENABLED" value="false" />
<option name="INSTANCE_FILTERS_ENABLED" value="false" />
<option name="CONDITION" value="" />
<option name="LOG_MESSAGE" value="" />
</breakpoint>
<breakpoint url="file://$PROJECT_DIR$/kernel/src/main/scala/State.scala" line="153" class="Class at State.scala:153" package="">
<option name="ENABLED" value="true" />
<option name="LOG_ENABLED" value="false" />
<option name="LOG_EXPRESSION_ENABLED" value="false" />
<option name="SUSPEND_POLICY" value="SuspendAll" />
<option name="COUNT_FILTER_ENABLED" value="false" />
<option name="COUNT_FILTER" value="0" />
<option name="CONDITION_ENABLED" value="false" />
<option name="CLASS_FILTERS_ENABLED" value="false" />
<option name="INSTANCE_FILTERS_ENABLED" value="false" />
<option name="CONDITION" value="" />
<option name="LOG_MESSAGE" value="" />
</breakpoint>
<breakpoint url="file://$PROJECT_DIR$/kernel/src/main/scala/State.scala" line="157" class="Class at State.scala:157" package="">
<option name="ENABLED" value="true" />
<option name="LOG_ENABLED" value="false" />
<option name="LOG_EXPRESSION_ENABLED" value="false" />
<option name="SUSPEND_POLICY" value="SuspendAll" />
<option name="COUNT_FILTER_ENABLED" value="false" />
<option name="COUNT_FILTER" value="0" />
<option name="CONDITION_ENABLED" value="false" />
<option name="CLASS_FILTERS_ENABLED" value="false" />
<option name="INSTANCE_FILTERS_ENABLED" value="false" />
<option name="CONDITION" value="" />
<option name="LOG_MESSAGE" value="" />
</breakpoint>
<breakpoint url="file://$PROJECT_DIR$/kernel/src/main/scala/State.scala" line="158" class="Class at State.scala:158" package="">
<option name="ENABLED" value="true" />
<option name="LOG_ENABLED" value="false" />
<option name="LOG_EXPRESSION_ENABLED" value="false" />
<option name="SUSPEND_POLICY" value="SuspendAll" />
<option name="COUNT_FILTER_ENABLED" value="false" />
<option name="COUNT_FILTER" value="0" />
<option name="CONDITION_ENABLED" value="false" />
<option name="CLASS_FILTERS_ENABLED" value="false" />
<option name="INSTANCE_FILTERS_ENABLED" value="false" />
<option name="CONDITION" value="" />
<option name="LOG_MESSAGE" value="" />
</breakpoint>
<breakpoint url="file://$PROJECT_DIR$/kernel/src/main/scala/State.scala" line="155" class="Class at State.scala:155" package="">
<option name="ENABLED" value="true" /> <option name="ENABLED" value="true" />
<option name="LOG_ENABLED" value="false" /> <option name="LOG_ENABLED" value="false" />
<option name="LOG_EXPRESSION_ENABLED" value="false" /> <option name="LOG_EXPRESSION_ENABLED" value="false" />
@ -153,37 +112,46 @@
</component> </component>
<component name="FileEditorManager"> <component name="FileEditorManager">
<leaf> <leaf>
<file leaf-file-name="Transaction.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/Transaction.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="86" column="0" selection-start="2898" selection-end="2898" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="Reactor.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/reactor/Reactor.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="0" column="4" selection-start="3" selection-end="3" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="PersistentStateful.java" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/PersistentStateful.java">
<provider selected="true" editor-type-id="text-editor">
<state line="8" column="51" selection-start="364" selection-end="364" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="Seq.scala" pinned="false" current="false" current-in-tab="false">
<entry file="jar://$PROJECT_DIR$/../../../bin/scala-2.7.3.final/src/scala-library-src.jar!/scala/Seq.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="197" column="6" selection-start="6523" selection-end="6523" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="ActiveObject.scala" pinned="false" current="false" current-in-tab="false"> <file leaf-file-name="ActiveObject.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/ActiveObject.scala"> <entry file="file://$PROJECT_DIR$/kernel/src/main/scala/ActiveObject.scala">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="112" column="52" selection-start="4116" selection-end="4116" vertical-scroll-proportion="-13.5"> <state line="0" column="109" selection-start="3" selection-end="3" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="ResultOrFailure.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/ResultOrFailure.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="56" column="6" selection-start="1411" selection-end="1411" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="GenericServer.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/GenericServer.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="188" column="6" selection-start="6146" selection-end="6146" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="InMemStateful.java" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemStateful.java">
<provider selected="true" editor-type-id="text-editor">
<state line="52" column="17" selection-start="1441" selection-end="1441" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
@ -192,28 +160,44 @@
<file leaf-file-name="State.scala" pinned="false" current="false" current-in-tab="false"> <file leaf-file-name="State.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/State.scala"> <entry file="file://$PROJECT_DIR$/kernel/src/main/scala/State.scala">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="158" column="0" selection-start="5462" selection-end="5462" vertical-scroll-proportion="0.0"> <state line="204" column="66" selection-start="7094" selection-end="7094" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="Transaction.scala" pinned="false" current="false" current-in-tab="false"> <file leaf-file-name="RandomAccessSeq.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/Transaction.scala"> <entry file="jar://$MAVEN_REPOSITORY$/org/scala-lang/scala-library/2.7.3/scala-library-2.7.3-sources.jar!/scala/RandomAccessSeq.scala">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="43" column="0" selection-start="1313" selection-end="1313" vertical-scroll-proportion="0.0"> <state line="245" column="6" selection-start="10181" selection-end="10181" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="InMemoryStateTest.java" pinned="false" current="true" current-in-tab="true"> <file leaf-file-name="Transaction.class" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java"> <entry file="file://$PROJECT_DIR$/WEB-INF/classes/se/scalablesolutions/akka/kernel/Transaction.class">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="88" column="46" selection-start="4602" selection-end="4602" vertical-scroll-proportion="0.7783933"> <state line="16" column="0" selection-start="1321" selection-end="1321" vertical-scroll-proportion="0.0">
<folding> <folding />
<element signature="imports" expanded="true" /> </state>
</folding> </provider>
</entry>
</file>
<file leaf-file-name="PersistentStateTest.java" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/PersistentStateTest.java">
<provider selected="true" editor-type-id="text-editor">
<state line="58" column="14" selection-start="2649" selection-end="2649" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="CassandraNode.scala" pinned="false" current="true" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/CassandraNode.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="0" column="4" selection-start="3" selection-end="3" vertical-scroll-proportion="0.0">
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -273,32 +257,6 @@
<option name="myItemId" value="akka-kernel" /> <option name="myItemId" value="akka-kernel" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Libraries" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.LibraryGroupNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka-kernel" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Libraries" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.LibraryGroupNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Maven: org.scala-lang:scala-library:2.7.3" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="scala-library-2.7.3.jar" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH> </PATH>
<PATH> <PATH>
<PATH_ELEMENT> <PATH_ELEMENT>
@ -331,14 +289,6 @@
<option name="myItemId" value="src" /> <option name="myItemId" value="src" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="test" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="scala" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH> </PATH>
<PATH> <PATH>
<PATH_ELEMENT> <PATH_ELEMENT>
@ -366,66 +316,6 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
</PATH> </PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka-kernel" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="kernel" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="src" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="main" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="scala" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="reactor" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka-kernel" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="kernel" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="src" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="main" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="scala" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="config" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH> <PATH>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="akka" /> <option name="myItemId" value="akka" />
@ -532,7 +422,7 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="InMemoryStateTest" /> <option name="myItemId" value="PersistentStateTest" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ClassTreeNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ClassTreeNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
</PATH> </PATH>
@ -566,10 +456,128 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="InMemStateful" /> <option name="myItemId" value="PersistentStateful" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ClassTreeNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ClassTreeNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
</PATH> </PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="WEB-INF" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="classes" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="se" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="scalablesolutions" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="WEB-INF" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="classes" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="se" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="scalablesolutions" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="kernel" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="WEB-INF" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="classes" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
</subPane> </subPane>
</component> </component>
<component name="ProjectReloadState"> <component name="ProjectReloadState">
@ -628,7 +636,7 @@
<recent name="se.scalablesolutions.akka.api" /> <recent name="se.scalablesolutions.akka.api" />
</key> </key>
</component> </component>
<component name="RunManager" selected="JUnit.InMemoryStateTest"> <component name="RunManager" selected="JUnit.PersistentStateTest">
<tempConfiguration default="false" name="Scala Console" type="ScalaScriptConsoleRunConfiguration" factoryName="Scala Console"> <tempConfiguration default="false" name="Scala Console" type="ScalaScriptConsoleRunConfiguration" factoryName="Scala Console">
<module name="" /> <module name="" />
<setting name="vmparams" value="" /> <setting name="vmparams" value="" />
@ -907,7 +915,37 @@
<option name="Make" value="false" /> <option name="Make" value="false" />
</method> </method>
</configuration> </configuration>
<list size="8"> <configuration default="false" name="ThreadBasedDispatcherTest" type="JUnit" factoryName="JUnit" enabled="false" merge="false" sample_coverage="true" runner="emma">
<module name="akka-kernel" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" value="" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="se.scalablesolutions.akka.kernel.reactor.ThreadBasedDispatcherTest" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="ADDITIONAL_CLASS_PATH" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="moduleWithDependencies" />
</option>
<envs />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="49238" />
<option name="TRANSPORT" value="0" />
<option name="LOCAL" value="true" />
</RunnerSettings>
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" />
<method>
<option name="Make" value="false" />
</method>
</configuration>
<list size="9">
<item index="0" class="java.lang.String" itemvalue="Application.Kernel" /> <item index="0" class="java.lang.String" itemvalue="Application.Kernel" />
<item index="1" class="java.lang.String" itemvalue="JUnit.CamelSpec" /> <item index="1" class="java.lang.String" itemvalue="JUnit.CamelSpec" />
<item index="2" class="java.lang.String" itemvalue="JUnit.InMemoryStateTest" /> <item index="2" class="java.lang.String" itemvalue="JUnit.InMemoryStateTest" />
@ -915,7 +953,8 @@
<item index="4" class="java.lang.String" itemvalue="JUnit.ActiveObjectGuiceConfiguratorTest" /> <item index="4" class="java.lang.String" itemvalue="JUnit.ActiveObjectGuiceConfiguratorTest" />
<item index="5" class="java.lang.String" itemvalue="JUnit.JerseySpec" /> <item index="5" class="java.lang.String" itemvalue="JUnit.JerseySpec" />
<item index="6" class="java.lang.String" itemvalue="JUnit.REST" /> <item index="6" class="java.lang.String" itemvalue="JUnit.REST" />
<item index="7" class="java.lang.String" itemvalue="Scala Console.Scala Console" /> <item index="7" class="java.lang.String" itemvalue="JUnit.ThreadBasedDispatcherTest" />
<item index="8" class="java.lang.String" itemvalue="Scala Console.Scala Console" />
</list> </list>
<configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false"> <configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false">
<Host>localhost</Host> <Host>localhost</Host>
@ -961,27 +1000,28 @@
</todo-panel> </todo-panel>
</component> </component>
<component name="ToolWindowManager"> <component name="ToolWindowManager">
<frame x="4" y="22" width="1435" height="878" extended-state="0" /> <frame x="4" y="22" width="1916" height="1178" extended-state="6" />
<editor active="true" /> <editor active="true" />
<layout> <layout>
<window_info id="Web Preview" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32908162" sideWeight="0.5" order="14" side_tool="false" /> <window_info id="Web Preview" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32908162" sideWeight="0.5" order="14" side_tool="false" />
<window_info id="Dataflow to this" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="15" side_tool="false" /> <window_info id="Dataflow to this" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="15" side_tool="false" />
<window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32876712" sideWeight="0.69260204" order="5" side_tool="false" /> <window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32876712" sideWeight="0.69260204" order="5" side_tool="false" />
<window_info id="Clojure REPL" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32908162" sideWeight="0.5" order="7" side_tool="false" />
<window_info id="Data Sources" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3294881" sideWeight="0.6875" order="3" side_tool="false" /> <window_info id="Data Sources" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3294881" sideWeight="0.6875" order="3" side_tool="false" />
<window_info id="IDEtalk" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3294881" sideWeight="0.59183675" order="4" side_tool="false" /> <window_info id="IDEtalk" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3294881" sideWeight="0.59183675" order="4" side_tool="false" />
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32780612" sideWeight="0.5" order="6" side_tool="false" /> <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32780612" sideWeight="0.5" order="6" side_tool="false" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.32972583" sideWeight="0.20663266" order="1" side_tool="false" /> <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.15854311" sideWeight="0.61715865" order="1" side_tool="false" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3252551" sideWeight="0.5" order="1" side_tool="false" /> <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32472324" sideWeight="0.5" order="1" side_tool="false" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24873829" sideWeight="0.74165636" order="0" side_tool="false" /> <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24873829" sideWeight="0.74165636" order="0" side_tool="false" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="5" side_tool="false" /> <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="5" side_tool="false" />
<window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.21811225" sideWeight="0.5" order="12" side_tool="false" /> <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.21771218" sideWeight="0.5" order="12" side_tool="false" />
<window_info id="Dependency Viewer" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="13" side_tool="false" /> <window_info id="Dependency Viewer" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="13" side_tool="false" />
<window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" /> <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24945927" sideWeight="0.6875" order="1" side_tool="false" /> <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24945927" sideWeight="0.6875" order="1" side_tool="false" />
<window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32780612" sideWeight="0.5" order="7" side_tool="false" /> <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32780612" sideWeight="0.5" order="7" side_tool="false" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="true" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.7844388" sideWeight="0.5" order="2" side_tool="false" x="4" y="22" width="1436" height="878" /> <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.37638375" sideWeight="0.5" order="2" side_tool="false" x="4" y="22" width="1436" height="878" />
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.39989322" sideWeight="0.75" order="0" side_tool="false" /> <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.39989322" sideWeight="0.75" order="0" side_tool="false" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33418366" sideWeight="0.5" order="3" side_tool="false" /> <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33394834" sideWeight="0.5" order="3" side_tool="false" />
<window_info id="IDEtalk Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="9" side_tool="false" /> <window_info id="IDEtalk Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="9" side_tool="false" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32780612" sideWeight="0.5" order="11" side_tool="false" /> <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32780612" sideWeight="0.5" order="11" side_tool="false" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" /> <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" />
@ -1032,117 +1072,115 @@
</buildFile> </buildFile>
</component> </component>
<component name="editorHistoryManager"> <component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/fun-test-java/pom.xml"> <entry file="jar://$MAVEN_REPOSITORY$/net/lag/configgy/1.3/configgy-1.3.jar!/net/lag/logging/Logger.class">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="6" column="27" selection-start="330" selection-end="330" vertical-scroll-proportion="0.0"> <state line="73" column="31" selection-start="6347" selection-end="6347" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/kernel/pom.xml"> <entry file="jar:///System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/../Classes/classes.jar!/java/util/logging/Level.class">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="38" column="60" selection-start="1203" selection-end="1203" vertical-scroll-proportion="0.0"> <state line="19" column="49" selection-start="878" selection-end="881" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/reactor/Future.scala"> <entry file="file://$PROJECT_DIR$/kernel/src/main/scala/Logging.scala">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="36" column="12" selection-start="1060" selection-end="1060" vertical-scroll-proportion="0.0"> <state line="24" column="27" selection-start="609" selection-end="609" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/ManagedActorScheduler.scala"> <entry file="file://$PROJECT_DIR$/kernel/src/main/scala/reactor/ProxyMessageDispatcher.scala">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="10" column="0" selection-start="163" selection-end="163" vertical-scroll-proportion="0.0"> <state line="12" column="6" selection-start="401" selection-end="401" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/Actor.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="4" column="46" selection-start="97" selection-end="97" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/reactor/Reactor.scala"> <entry file="file://$PROJECT_DIR$/kernel/src/main/scala/reactor/Reactor.scala">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="75" column="0" selection-start="2051" selection-end="2051" vertical-scroll-proportion="0.0"> <state line="0" column="4" selection-start="3" selection-end="3" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/kernel/src/test/scala/ActorTest.scala"> <entry file="file://$PROJECT_DIR$/kernel/src/main/resources/META-INF/services/org/apache/camel/component/akka">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="0" column="46" selection-start="46" selection-end="46" vertical-scroll-proportion="0.0"> <state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/scala-lang/scala-library/2.7.3/scala-library-2.7.3-sources.jar!/scala/List.scala"> <entry file="file://$PROJECT_DIR$/WEB-INF/classes/se/scalablesolutions/akka/kernel/CassandraNode.class">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="804" column="0" selection-start="24740" selection-end="24740" vertical-scroll-proportion="0.3482906"> <state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/config/ActiveObjectGuiceConfigurator.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="91" column="0" selection-start="3931" selection-end="3931" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/Transaction.scala"> <entry file="file://$PROJECT_DIR$/kernel/src/main/scala/Transaction.scala">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="43" column="0" selection-start="1313" selection-end="1313" vertical-scroll-proportion="0.0"> <state line="86" column="0" selection-start="2898" selection-end="2898" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemStateful.java"> <entry file="file://$PROJECT_DIR$/WEB-INF/classes/se/scalablesolutions/akka/kernel/Transaction.class">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="52" column="17" selection-start="1441" selection-end="1441" vertical-scroll-proportion="0.0"> <state line="16" column="0" selection-start="1321" selection-end="1321" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/State.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="158" column="0" selection-start="5462" selection-end="5462" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/GenericServer.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="188" column="6" selection-start="6146" selection-end="6146" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/ResultOrFailure.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="56" column="6" selection-start="1411" selection-end="1411" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/ActiveObject.scala"> <entry file="file://$PROJECT_DIR$/kernel/src/main/scala/ActiveObject.scala">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="112" column="52" selection-start="4116" selection-end="4116" vertical-scroll-proportion="-13.5"> <state line="0" column="109" selection-start="3" selection-end="3" vertical-scroll-proportion="0.0">
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java"> <entry file="file://$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/PersistentStateTest.java">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state line="88" column="46" selection-start="4602" selection-end="4602" vertical-scroll-proportion="0.7783933"> <state line="58" column="14" selection-start="2649" selection-end="2649" vertical-scroll-proportion="0.0">
<folding> <folding />
<element signature="imports" expanded="true" /> </state>
</folding> </provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/scala-lang/scala-library/2.7.3/scala-library-2.7.3-sources.jar!/scala/RandomAccessSeq.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="245" column="6" selection-start="10181" selection-end="10181" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="jar://$PROJECT_DIR$/../../../bin/scala-2.7.3.final/src/scala-library-src.jar!/scala/Seq.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="197" column="6" selection-start="6523" selection-end="6523" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/PersistentStateful.java">
<provider selected="true" editor-type-id="text-editor">
<state line="8" column="51" selection-start="364" selection-end="364" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/State.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="204" column="66" selection-start="7094" selection-end="7094" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/CassandraNode.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="0" column="4" selection-start="3" selection-end="3" vertical-scroll-proportion="0.0">
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>

View file

@ -35,6 +35,8 @@
<Tables> <Tables>
<Table Name="akka"> <Table Name="akka">
<ColumnFamily ColumnSort="Name" Name="map"/> <ColumnFamily ColumnSort="Name" Name="map"/>
<ColumnFamily ColumnSort="Name" Name="vector"/>
<ColumnFamily ColumnSort="Name" Name="ref"/>
<!--ColumnFamily ColumnType="Super" ColumnSort="Name" Name="Super2"/--> <!--ColumnFamily ColumnType="Super" ColumnSort="Name" Name="Super2"/-->
</Table> </Table>
</Tables> </Tables>

View file

@ -95,7 +95,7 @@ public class ActiveObjectGuiceConfiguratorTest extends TestCase {
try { try {
foo.longRunning(); foo.longRunning();
fail("exception should have been thrown"); fail("exception should have been thrown");
} catch (se.scalablesolutions.akka.kernel.ActiveObjectInvocationTimeoutException e) { } catch (se.scalablesolutions.akka.kernel.reactor.FutureTimeoutException e) {
} }
} }

View file

@ -27,8 +27,8 @@ public class PersistentStateTest extends TestCase {
new RestartStrategy(new AllForOne(), 3, 5000), new RestartStrategy(new AllForOne(), 3, 5000),
new Component[] { new Component[] {
new Component(PersistentStateful.class, new LifeCycle(new Permanent(), 1000), 10000000), new Component(PersistentStateful.class, new LifeCycle(new Permanent(), 1000), 10000000),
new Component(PersistentFailer.class, new LifeCycle(new Permanent(), 1000), 1000), new Component(PersistentFailer.class, new LifeCycle(new Permanent(), 1000), 1000)
new Component(PersistentClasher.class, new LifeCycle(new Permanent(), 1000), 100000) //new Component(PersistentClasher.class, new LifeCycle(new Permanent(), 1000), 100000)
}).supervise(); }).supervise();
} }
@ -38,21 +38,62 @@ public class PersistentStateTest extends TestCase {
public void testShouldNotRollbackStateForStatefulServerInCaseOfSuccess() { public void testShouldNotRollbackStateForStatefulServerInCaseOfSuccess() {
PersistentStateful stateful = conf.getActiveObject(PersistentStateful.class); PersistentStateful stateful = conf.getActiveObject(PersistentStateful.class);
stateful.setState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init"); // set init state stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init"); // set init state
stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // transactional stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // transactional
stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // to trigger commit stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // to trigger commit
assertEquals("new state", stateful.getState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess")); assertEquals("new state", stateful.getMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess"));
} }
public void testShouldRollbackStateForStatefulServerInCaseOfFailure() { public void testMapShouldRollbackStateForStatefulServerInCaseOfFailure() {
PersistentStateful stateful = conf.getActiveObject(PersistentStateful.class);
stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init"); // set init state
PersistentFailer failer = conf.getActiveObject(PersistentFailer.class);
try {
stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer); // call failing transactional method
fail("should have thrown an exception");
} catch (RuntimeException e) {
} // expected
assertEquals("init", stateful.getMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure")); // check that state is == init state
}
public void testVectorShouldNotRollbackStateForStatefulServerInCaseOfSuccess() {
PersistentStateful stateful = conf.getActiveObject(PersistentStateful.class); PersistentStateful stateful = conf.getActiveObject(PersistentStateful.class);
stateful.setState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init"); // set init state stateful.setVectorState("init"); // set init state
PersistentFailer failer = conf.getActiveObject(PersistentFailer.class); stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // transactional
try { stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // to trigger commit
stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer); // call failing transactional method assertEquals("new state", stateful.getVectorState());
fail("should have thrown an exception");
} catch (RuntimeException e) {
} // expected
assertEquals("init", stateful.getState("testShouldRollbackStateForStatefulServerInCaseOfFailure")); // check that state is == init state
} }
public void testVectorShouldRollbackStateForStatefulServerInCaseOfFailure() {
PersistentStateful stateful = conf.getActiveObject(PersistentStateful.class);
stateful.setVectorState("init"); // set init state
PersistentFailer failer = conf.getActiveObject(PersistentFailer.class);
try {
stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer); // call failing transactional method
fail("should have thrown an exception");
} catch (RuntimeException e) {
} // expected
assertEquals("init", stateful.getVectorState()); // check that state is == init state
}
/*
public void testRefShouldNotRollbackStateForStatefulServerInCaseOfSuccess() {
PersistentStateful stateful = conf.getActiveObject(PersistentStateful.class);
stateful.setRefState("init"); // set init state
stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // transactional
stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // to trigger commit
assertEquals("new state", stateful.getRefState());
}
public void testRefShouldRollbackStateForStatefulServerInCaseOfFailure() {
PersistentStateful stateful = conf.getActiveObject(PersistentStateful.class);
stateful.setRefState("init"); // set init state
PersistentFailer failer = conf.getActiveObject(PersistentFailer.class);
try {
stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer); // call failing transactional method
fail("should have thrown an exception");
} catch (RuntimeException e) {
} // expected
assertEquals("init", stateful.getRefState()); // check that state is == init state
}
*/
} }

View file

@ -1,42 +1,56 @@
package se.scalablesolutions.akka.api; package se.scalablesolutions.akka.api;
import se.scalablesolutions.akka.kernel.TransactionalMap; import se.scalablesolutions.akka.kernel.*;
import se.scalablesolutions.akka.kernel.CassandraPersistentTransactionalMap;
import se.scalablesolutions.akka.annotation.transactional; import se.scalablesolutions.akka.annotation.transactional;
import se.scalablesolutions.akka.annotation.state;
public class PersistentStateful { public class PersistentStateful {
private TransactionalMap state = new CassandraPersistentTransactionalMap(this); private TransactionalMap mapState = new CassandraPersistentTransactionalMap(this);
private TransactionalVector vectorState = new CassandraPersistentTransactionalVector(this);
//private TransactionalRef refState = new CassandraPersistentTransactionalRef(this);
public String getState(String key) { public String getMapState(String key) {
return (String)state.get(key).get(); return (String) mapState.get(key).get();
} }
public void setState(String key, String msg) { public String getVectorState() {
state.put(key, msg); return (String) vectorState.first();
} }
// public String getRefState() {
// return (String) refState.get().get();
// }
public void setMapState(String key, String msg) {
mapState.put(key, msg);
}
public void setVectorState(String msg) {
vectorState.add(msg);
}
// public void setRefState(String msg) {
// refState.swap(msg);
// }
@transactional @transactional
public void success(String key, String msg) { public void success(String key, String msg) {
state.put(key, msg); mapState.put(key, msg);
vectorState.add(msg);
// refState.swap(msg);
} }
@transactional @transactional
public void failure(String key, String msg, PersistentFailer failer) { public void failure(String key, String msg, PersistentFailer failer) {
state.put(key, msg); mapState.put(key, msg);
vectorState.add(msg);
// refState.swap(msg);
failer.fail(); failer.fail();
} }
@transactional @transactional
public void clashOk(String key, String msg, PersistentClasher clasher) { public void thisMethodHangs(String key, String msg, PersistentFailer failer) {
state.put(key, msg); setMapState(key, msg);
clasher.clash();
}
@transactional
public void clashNotOk(String key, String msg, PersistentClasher clasher) {
state.put(key, msg);
clasher.clash();
clasher.clash();
} }
} }

View file

@ -95,6 +95,11 @@ sealed class TransactionalAroundAdvice(target: Class[_],
server.transactionalMaps = maps server.transactionalMaps = maps
server.transactionalVectors = vectors server.transactionalVectors = vectors
import kernel.reactor._
private[this] var dispatcher = new ProxyMessageDispatcher
private[this] var mailbox = dispatcher.messageQueue
dispatcher.start
import ActiveObject.threadBoundTx import ActiveObject.threadBoundTx
private[this] var activeTx: Option[Transaction] = None private[this] var activeTx: Option[Transaction] = None
@ -113,12 +118,13 @@ sealed class TransactionalAroundAdvice(target: Class[_],
else handleResult(sendAndReceiveEventually(joinpoint)) else handleResult(sendAndReceiveEventually(joinpoint))
} finally { } finally {
decrementTransaction decrementTransaction
tryToPrecommitTransaction if (isTransactionAborted) removeTransactionIfTopLevel
removeTransactionIfTopLevel else tryToPrecommitTransaction
} }
result result
} }
private def isTransactionAborted = activeTx.isDefined && activeTx.get.isAborted
private def incrementTransaction = if (activeTx.isDefined) activeTx.get.increment private def incrementTransaction = if (activeTx.isDefined) activeTx.get.increment
private def decrementTransaction = if (activeTx.isDefined) activeTx.get.decrement private def decrementTransaction = if (activeTx.isDefined) activeTx.get.decrement
private def removeTransactionIfTopLevel = private def removeTransactionIfTopLevel =
@ -148,8 +154,7 @@ sealed class TransactionalAroundAdvice(target: Class[_],
private def tryToCommitTransaction = if (activeTx.isDefined) { private def tryToCommitTransaction = if (activeTx.isDefined) {
val tx = activeTx.get val tx = activeTx.get
tx.commit(server) tx.commit(server)
threadBoundTx.set(None) removeTransactionIfTopLevel
activeTx = None
} }
private def handleResult(result: ResultOrFailure[AnyRef]): AnyRef = { private def handleResult(result: ResultOrFailure[AnyRef]): AnyRef = {
@ -166,19 +171,31 @@ sealed class TransactionalAroundAdvice(target: Class[_],
case None => {} // no tx; nothing to do case None => {} // no tx; nothing to do
case Some(tx) => case Some(tx) =>
tx.rollback(server) tx.rollback(server)
threadBoundTx.set(Some(tx))
} }
private def sendOneWay(joinpoint: JoinPoint) = server ! Invocation(joinpoint, activeTx) private def sendOneWay(joinpoint: JoinPoint) =
mailbox.append(new MessageHandle(this, Invocation(joinpoint, activeTx), new NullFutureResult))
private def sendAndReceiveEventually(joinpoint: JoinPoint): ResultOrFailure[AnyRef] = { private def sendAndReceiveEventually(joinpoint: JoinPoint): ResultOrFailure[AnyRef] = {
server !!! (Invocation(joinpoint, activeTx), { val future = postMessageToMailboxAndCreateFutureResultWithTimeout(Invocation(joinpoint, activeTx), 1000)
var resultOrFailure = ResultOrFailure(activeTx) future.await_?
resultOrFailure() = throw new ActiveObjectInvocationTimeoutException("Invocation to active object [" + targetInstance.getClass.getName + "] timed out after " + server.timeout + " milliseconds") getResultOrThrowException(future)
resultOrFailure
})
} }
private def postMessageToMailboxAndCreateFutureResultWithTimeout(
message: AnyRef, timeout: Long): CompletableFutureResult = {
val future = new DefaultCompletableFutureResult(timeout)
mailbox.append(new MessageHandle(this, message, future))
future
}
private def getResultOrThrowException[T](future: FutureResult): ResultOrFailure[AnyRef] =
if (future.exception.isDefined) {
var resultOrFailure = ResultOrFailure(activeTx)
resultOrFailure() = throw future.exception.get
resultOrFailure
} else ResultOrFailure(future.result.get, activeTx)
/** /**
* Search for transactional items for a specific target instance, crawl the class hierarchy recursively up to the top. * Search for transactional items for a specific target instance, crawl the class hierarchy recursively up to the top.
*/ */

View file

@ -26,6 +26,7 @@ class ActorMessageHandler(val actor: Actor) extends MessageHandler {
trait Actor { trait Actor {
private[this] val linkedActors = new ConcurrentSkipListSet[Actor] private[this] val linkedActors = new ConcurrentSkipListSet[Actor]
private[this] var dispatcher: MessageDispatcher = _
private[this] var mailbox: MessageQueue = _ private[this] var mailbox: MessageQueue = _
private[this] var senderFuture: Option[CompletableFutureResult] = None private[this] var senderFuture: Option[CompletableFutureResult] = None
@volatile private var isRunning: Boolean = false @volatile private var isRunning: Boolean = false
@ -119,12 +120,13 @@ trait Actor {
if (!isRunning) { if (!isRunning) {
dispatcherType match { dispatcherType match {
case EventBased => case EventBased =>
mailbox = EventBasedDispatcher.messageQueue dispatcher = new EventBasedDispatcher
EventBasedDispatcher.registerHandler(this, new ActorMessageHandler(this))
case ThreadBased => case ThreadBased =>
mailbox = ThreadBasedDispatcher.messageQueue dispatcher = new ThreadBasedDispatcher
ThreadBasedDispatcher.registerHandler(this, new ActorMessageHandler(this))
} }
mailbox = dispatcher.messageQueue
dispatcher.registerHandler(this, new ActorMessageHandler(this))
dispatcher.start
isRunning = true isRunning = true
} }
} }
@ -132,10 +134,7 @@ trait Actor {
def stop = def stop =
if (isRunning) { if (isRunning) {
this ! Stop("Actor gracefully stopped") this ! Stop("Actor gracefully stopped")
dispatcherType match { dispatcher.unregisterHandler(this)
case EventBased => EventBasedDispatcher.unregisterHandler(this)
case ThreadBased => ThreadBasedDispatcher.unregisterHandler(this)
}
isRunning = false isRunning = false
} else throw new IllegalStateException("Actor has not been started, you need to invoke 'actor.start' before using it") } else throw new IllegalStateException("Actor has not been started, you need to invoke 'actor.start' before using it")

View file

@ -20,7 +20,9 @@ final object CassandraNode extends Logging {
val TABLE_NAME = "akka" val TABLE_NAME = "akka"
val ACTOR_KEY_PREFIX = "actor" val ACTOR_KEY_PREFIX = "actor"
val ACTOR_MAP_COLUMN_FAMILY = "map" val ACTOR_MAP_COLUMN_FAMILY = "map"
val ACTOR_VECTOR_COLUMN_FAMILY = "vector"
val ACTOR_REF_COLUMN_FAMILY = "ref"
// TODO: make pluggable (JSON, Thrift, Protobuf etc.) // TODO: make pluggable (JSON, Thrift, Protobuf etc.)
private[this] var serializer: Serializer = new JavaSerializationSerializer private[this] var serializer: Serializer = new JavaSerializationSerializer
@ -40,17 +42,56 @@ final object CassandraNode extends Logging {
def stop = {} def stop = {}
def insertActorStorageEntry(actorName: String, entry: String, content: AnyRef) = { // ===============================================================
// For Ref
// ===============================================================
// ===============================================================
// For Vector
// ===============================================================
def insertVectorStorageEntryFor(name: String, element: AnyRef) = {
server.insert( server.insert(
TABLE_NAME, TABLE_NAME,
ACTOR_KEY_PREFIX + ":" + actorName, ACTOR_KEY_PREFIX + ":" + name,
ACTOR_MAP_COLUMN_FAMILY + ":" + entry, ACTOR_VECTOR_COLUMN_FAMILY + ":" + getVectorStorageSizeFor(name),
serializer.out(content), serializer.out(element),
System.currentTimeMillis, System.currentTimeMillis,
false) // FIXME: what is this flag for? false) // FIXME: what is this flag for?
} }
def insertActorStorageEntries(actorName: String, entries: List[Tuple2[String, AnyRef]]) = { def getVectorStorageEntryFor(name: String, index: Int): AnyRef = {
try {
val column = server.get_column(TABLE_NAME, ACTOR_KEY_PREFIX + ":" + name, ACTOR_VECTOR_COLUMN_FAMILY + ":" + index)
serializer.in(column.value)
} catch {
case e => throw new Predef.NoSuchElementException(e.getMessage)
}
}
def getVectorStorageRangeFor(name: String, start: Int, count: Int): List[AnyRef] =
server.get_slice(TABLE_NAME, ACTOR_KEY_PREFIX + ":" + name, ACTOR_VECTOR_COLUMN_FAMILY, start, count)
.toArray.toList.asInstanceOf[List[Tuple2[String, AnyRef]]].map(tuple => tuple._2)
def getVectorStorageSizeFor(name: String): Int =
server.get_column_count(TABLE_NAME, ACTOR_KEY_PREFIX + ":" + name, ACTOR_VECTOR_COLUMN_FAMILY)
// ===============================================================
// For Map
// ===============================================================
def insertMapStorageEntryFor(name: String, key: String, value: AnyRef) = {
println("PUT: " + name + " " + key + " " + value)
server.insert(
TABLE_NAME,
ACTOR_KEY_PREFIX + ":" + name,
ACTOR_MAP_COLUMN_FAMILY + ":" + key,
serializer.out(value),
System.currentTimeMillis,
false) // FIXME: what is this flag for?
}
def insertMapStorageEntriesFor(name: String, entries: List[Tuple2[String, AnyRef]]) = {
import java.util.{Map, HashMap, List, ArrayList} import java.util.{Map, HashMap, List, ArrayList}
val columns: Map[String, List[column_t]] = new HashMap val columns: Map[String, List[column_t]] = new HashMap
for (entry <- entries) { for (entry <- entries) {
@ -60,19 +101,20 @@ final object CassandraNode extends Logging {
} }
server.batch_insert(new batch_mutation_t( server.batch_insert(new batch_mutation_t(
TABLE_NAME, TABLE_NAME,
ACTOR_KEY_PREFIX + ":" + actorName, ACTOR_KEY_PREFIX + ":" + name,
columns), columns),
false) // non-blocking false) // non-blocking
} }
def getActorStorageEntryFor(actorName: String, entry: AnyRef): Option[AnyRef] = { def getMapStorageEntryFor(name: String, key: AnyRef): Option[AnyRef] = {
println("GET: " + name + " " + key)
try { try {
val column = server.get_column(TABLE_NAME, ACTOR_KEY_PREFIX + ":" + actorName, ACTOR_MAP_COLUMN_FAMILY + ":" + entry) val column = server.get_column(TABLE_NAME, ACTOR_KEY_PREFIX + ":" + name, ACTOR_MAP_COLUMN_FAMILY + ":" + key)
Some(serializer.in(column.value)) Some(serializer.in(column.value))
} catch { case e => None } } catch { case e => None }
} }
def getActorStorageFor(actorName: String): List[Tuple2[String, AnyRef]] = { def getMapStorageFor(name: String): List[Tuple2[String, AnyRef]] = {
val columns = server.get_columns_since(TABLE_NAME, ACTOR_KEY_PREFIX, ACTOR_MAP_COLUMN_FAMILY, -1) val columns = server.get_columns_since(TABLE_NAME, ACTOR_KEY_PREFIX, ACTOR_MAP_COLUMN_FAMILY, -1)
.toArray.toList.asInstanceOf[List[org.apache.cassandra.service.column_t]] .toArray.toList.asInstanceOf[List[org.apache.cassandra.service.column_t]]
for { for {
@ -81,14 +123,14 @@ final object CassandraNode extends Logging {
} yield col } yield col
} }
def getActorStorageSizeFor(actorName: String): Int = def getMapStorageSizeFor(name: String): Int =
server.get_column_count(TABLE_NAME, ACTOR_KEY_PREFIX + ":" + actorName, ACTOR_MAP_COLUMN_FAMILY) server.get_column_count(TABLE_NAME, ACTOR_KEY_PREFIX + ":" + name, ACTOR_MAP_COLUMN_FAMILY)
def removeActorStorageFor(actorName: String) = def removeMapStorageFor(name: String) =
server.remove(TABLE_NAME, ACTOR_KEY_PREFIX + ":" + actorName, ACTOR_MAP_COLUMN_FAMILY, System.currentTimeMillis, false) server.remove(TABLE_NAME, ACTOR_KEY_PREFIX + ":" + name, ACTOR_MAP_COLUMN_FAMILY, System.currentTimeMillis, false)
def getActorStorageRange(actorName: String, start: Int, count: Int): List[Tuple2[String, AnyRef]] = def getMapStorageRangeFor(name: String, start: Int, count: Int): List[Tuple2[String, AnyRef]] =
server.get_slice(TABLE_NAME, ACTOR_KEY_PREFIX + ":" + actorName, ACTOR_MAP_COLUMN_FAMILY, start, count) server.get_slice(TABLE_NAME, ACTOR_KEY_PREFIX + ":" + name, ACTOR_MAP_COLUMN_FAMILY, start, count)
.toArray.toList.asInstanceOf[List[Tuple2[String, AnyRef]]] .toArray.toList.asInstanceOf[List[Tuple2[String, AnyRef]]]
} }

View file

@ -48,7 +48,7 @@ object DataFlow {
/** /**
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a> * @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/ */
sealed class DataFlowVariable[T] { sealed class DataFlowVariable[T] {
private sealed abstract class DataFlowVariableMessage private sealed abstract class DataFlowVariableMessage
private case class Set[T](value: T) extends DataFlowVariableMessage private case class Set[T](value: T) extends DataFlowVariableMessage

View file

@ -78,7 +78,7 @@ object Kernel extends Logging {
println("=================================================") println("=================================================")
var start = System.currentTimeMillis var start = System.currentTimeMillis
for (i <- 1 to NR_ENTRIES) CassandraNode.insertActorStorageEntry("test", i.toString, "data") for (i <- 1 to NR_ENTRIES) CassandraNode.insertMapStorageEntryFor("test", i.toString, "data")
var end = System.currentTimeMillis var end = System.currentTimeMillis
println("Writes per second: " + NR_ENTRIES / ((end - start).toDouble / 1000)) println("Writes per second: " + NR_ENTRIES / ((end - start).toDouble / 1000))
@ -109,7 +109,7 @@ java.lang.ClassCastException: [B cannot be cast to org.apache.cassandra.db.Write
*/ */
println("=================================================") println("=================================================")
start = System.currentTimeMillis start = System.currentTimeMillis
for (i <- 1 to NR_ENTRIES) CassandraNode.getActorStorageEntryFor("test", i.toString) for (i <- 1 to NR_ENTRIES) CassandraNode.getMapStorageEntryFor("test", i.toString)
end = System.currentTimeMillis end = System.currentTimeMillis
println("Reads per second: " + NR_ENTRIES / ((end - start).toDouble / 1000)) println("Reads per second: " + NR_ENTRIES / ((end - start).toDouble / 1000))

View file

@ -4,6 +4,7 @@
package se.scalablesolutions.akka.kernel package se.scalablesolutions.akka.kernel
import java.util.logging.Level
import net.lag.configgy.Config import net.lag.configgy.Config
import net.lag.logging.Logger import net.lag.logging.Logger
@ -19,7 +20,12 @@ import java.net.UnknownHostException;
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a> * @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/ */
trait Logging { trait Logging {
@transient val log = Logger.get(this.getClass.getName) @transient val log = {
val log = Logger.get(this.getClass.getName)
log.setLevel(Level.ALL)
log
}
} }
/** /**

View file

@ -47,7 +47,7 @@ class ResultOrFailure[Payload](payload: Payload, val tx: Option[Transaction]) {
def apply() = contents match { def apply() = contents match {
case Right(payload) => payload case Right(payload) => payload
case Left(e) => throw e.fillInStackTrace case Left(e) => throw e
} }
override def toString(): String = "ResultOrFailure[" + contents + "]" override def toString(): String = "ResultOrFailure[" + contents + "]"

View file

@ -4,6 +4,7 @@
package se.scalablesolutions.akka.kernel package se.scalablesolutions.akka.kernel
import org.codehaus.aspectwerkz.proxy.Uuid
import se.scalablesolutions.akka.collection._ import se.scalablesolutions.akka.collection._
import scala.collection.mutable.HashMap import scala.collection.mutable.HashMap
@ -11,6 +12,7 @@ import scala.collection.mutable.HashMap
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a> * @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/ */
trait Transactional { trait Transactional {
val uuid = Uuid.newUuid.toString
private[kernel] def begin private[kernel] def begin
private[kernel] def commit private[kernel] def commit
private[kernel] def rollback private[kernel] def rollback
@ -60,7 +62,7 @@ class InMemoryTransactionalMap[K, V] extends TransactionalMap[K, V] {
} }
/** /**
* Base class for all persistent state implementations should extend. * Base class for all persistent transactional map implementations should extend.
* Implements a Unit of Work, records changes into a change set. * Implements a Unit of Work, records changes into a change set.
* *
* Not thread-safe, but should only be using from within an Actor, e.g. one single thread at a time. * Not thread-safe, but should only be using from within an Actor, e.g. one single thread at a time.
@ -68,6 +70,8 @@ class InMemoryTransactionalMap[K, V] extends TransactionalMap[K, V] {
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a> * @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/ */
abstract class PersistentTransactionalMap[K, V] extends TransactionalMap[K, V] { abstract class PersistentTransactionalMap[K, V] extends TransactionalMap[K, V] {
// FIXME: need to handle remove in another changeSet
protected[kernel] val changeSet = new HashMap[K, V] protected[kernel] val changeSet = new HashMap[K, V]
def getRange(start: Int, count: Int) def getRange(start: Int, count: Int)
@ -87,56 +91,56 @@ abstract class PersistentTransactionalMap[K, V] extends TransactionalMap[K, V] {
} }
/** /**
* Implements a persistent state based on the Cassandra distributed P2P key-value storage. * Implements a persistent transactional map based on the Cassandra distributed P2P key-value storage.
* *
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a> * @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/ */
class CassandraPersistentTransactionalMap(actorNameInstance: AnyRef) class CassandraPersistentTransactionalMap(actorNameInstance: AnyRef)
extends PersistentTransactionalMap[String, AnyRef] { extends PersistentTransactionalMap[String, AnyRef] {
val actorName = actorNameInstance.getClass.getName val actorName = actorNameInstance.getClass.getName
override def getRange(start: Int, count: Int) = CassandraNode.getActorStorageRange(actorName, start, count) override def getRange(start: Int, count: Int) = CassandraNode.getMapStorageRangeFor(uuid, start, count)
// ---- For Transactional ---- // ---- For Transactional ----
override def commit = { override def commit = {
// FIXME: should use batch function once the bug is resolved // FIXME: should use batch function once the bug is resolved
for (entry <- changeSet) { for (entry <- changeSet) {
val (key, value) = entry val (key, value) = entry
CassandraNode.insertActorStorageEntry(actorName, key, value) CassandraNode.insertMapStorageEntryFor(uuid, key, value)
} }
} }
// ---- Overriding scala.collection.mutable.Map behavior ---- // ---- Overriding scala.collection.mutable.Map behavior ----
override def clear = CassandraNode.removeActorStorageFor(actorName) override def clear = CassandraNode.removeMapStorageFor(uuid)
override def contains(key: String): Boolean = CassandraNode.getActorStorageEntryFor(actorName, key).isDefined override def contains(key: String): Boolean = CassandraNode.getMapStorageEntryFor(uuid, key).isDefined
override def size: Int = CassandraNode.getActorStorageSizeFor(actorName) override def size: Int = CassandraNode.getMapStorageSizeFor(uuid)
// ---- For scala.collection.mutable.Map ---- // ---- For scala.collection.mutable.Map ----
override def get(key: String): Option[AnyRef] = CassandraNode.getActorStorageEntryFor(actorName, key) override def get(key: String): Option[AnyRef] = CassandraNode.getMapStorageEntryFor(uuid, key)
override def elements: Iterator[Tuple2[String, AnyRef]] = { override def elements: Iterator[Tuple2[String, AnyRef]] = {
new Iterator[Tuple2[String, AnyRef]] { new Iterator[Tuple2[String, AnyRef]] {
private val originalList: List[Tuple2[String, AnyRef]] = CassandraNode.getActorStorageFor(actorName) private val originalList: List[Tuple2[String, AnyRef]] = CassandraNode.getMapStorageFor(uuid)
private var elements = originalList.reverse private var elements = originalList.reverse
override def next: Tuple2[String, AnyRef]= synchronized { override def next: Tuple2[String, AnyRef]= synchronized {
val element = elements.head val element = elements.head
elements = elements.tail elements = elements.tail
element element
} }
override def hasNext: Boolean = synchronized { !elements.isEmpty } override def hasNext: Boolean = synchronized { !elements.isEmpty }
} }
} }
} }
/** /**
* TODO: extend scala.Seq
* Base for all transactional vector implementations. * Base for all transactional vector implementations.
* *
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a> * @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/ */
abstract class TransactionalVector[T] extends Transactional with RandomAccessSeq[T] { abstract class TransactionalVector[T] extends Transactional with RandomAccessSeq[T] {
def add(elem: T) def add(elem: T)
def get(index: Int): T def get(index: Int): T
def getRange(start: Int, count: Int): List[T]
} }
/** /**
@ -150,8 +154,9 @@ class InMemoryTransactionalVector[T] extends TransactionalVector[T] {
private[kernel] var state: Vector[T] = EmptyVector private[kernel] var state: Vector[T] = EmptyVector
private[kernel] var snapshot = state private[kernel] var snapshot = state
override def add(elem: T) = state = state + elem def add(elem: T) = state = state + elem
override def get(index: Int): T = state(index) def get(index: Int): T = state(index)
def getRange(start: Int, count: Int): List[T] = state.slice(start, count).toList.asInstanceOf[List[T]]
// ---- For Transactional ---- // ---- For Transactional ----
override def begin = snapshot = state override def begin = snapshot = state
@ -165,6 +170,52 @@ class InMemoryTransactionalVector[T] extends TransactionalVector[T] {
override def toList: List[T] = state.toList override def toList: List[T] = state.toList
} }
/**
* Base class for all persistent transactional vector implementations should extend.
* Implements a Unit of Work, records changes into a change set.
*
* Not thread-safe, but should only be using from within an Actor, e.g. one single thread at a time.
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
abstract class PersistentTransactionalVector[T] extends TransactionalVector[T] {
// FIXME: need to handle remove in another changeSet
protected[kernel] var changeSet: List[T] = Nil
// ---- For Transactional ----
override def begin = changeSet = Nil
override def rollback = {}
// ---- For TransactionalVector ----
override def add(value: T) = changeSet ::= value
}
/**
* Implements a persistent transactional vector based on the Cassandra distributed P2P key-value storage.
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
class CassandraPersistentTransactionalVector(actorNameInstance: AnyRef)
extends PersistentTransactionalVector[AnyRef] {
val actorName = actorNameInstance.getClass.getName
// ---- For TransactionalVector ----
override def get(index: Int): AnyRef = CassandraNode.getVectorStorageEntryFor(uuid, index)
override def getRange(start: Int, count: Int): List[AnyRef] = CassandraNode.getVectorStorageRangeFor(uuid, start, count)
override def length: Int = CassandraNode.getVectorStorageSizeFor(uuid)
override def apply(index: Int): AnyRef = get(index)
override def first: AnyRef = get(0)
override def last: AnyRef = get(length)
// ---- For Transactional ----
override def commit = {
// FIXME: should use batch function once the bug is resolved
for (element <- changeSet) CassandraNode.insertVectorStorageEntryFor(uuid, element)
}
}
/** /**
* Implements a transactional reference. * Implements a transactional reference.
* *

View file

@ -49,8 +49,8 @@ class Transaction extends Logging {
def begin(server: GenericServerContainer) = synchronized { def begin(server: GenericServerContainer) = synchronized {
ensureIsActiveOrNew ensureIsActiveOrNew
if (status == TransactionStatus.New) log.info("Server [%s] is starting NEW transaction [%s]", server.id, this) if (status == TransactionStatus.New) log.debug("Server [%s] is starting NEW transaction [%s]", server.id, this)
else log.info("Server [%s] is participating in transaction", server) else log.debug("Server [%s] is participating in transaction", server)
server.transactionalItems.foreach(_.begin) server.transactionalItems.foreach(_.begin)
participants + server participants + server
status = TransactionStatus.Active status = TransactionStatus.Active
@ -58,14 +58,14 @@ class Transaction extends Logging {
def precommit(server: GenericServerContainer) = synchronized { def precommit(server: GenericServerContainer) = synchronized {
if (status == TransactionStatus.Active) { if (status == TransactionStatus.Active) {
log.info("Pre-committing transaction [%s] for server [%s]", this, server.id) log.debug("Pre-committing transaction [%s] for server [%s]", this, server.id)
precommitted + server precommitted + server
} }
} }
def commit(server: GenericServerContainer) = synchronized { def commit(server: GenericServerContainer) = synchronized {
if (status == TransactionStatus.Active) { if (status == TransactionStatus.Active) {
log.info("Committing transaction [%s] for server [%s]", this, server.id) log.debug("Committing transaction [%s] for server [%s]", this, server.id)
val haveAllPreCommitted = val haveAllPreCommitted =
if (participants.size == precommitted.size) {{ if (participants.size == precommitted.size) {{
for (server <- participants) yield { for (server <- participants) yield {
@ -85,18 +85,23 @@ class Transaction extends Logging {
def rollback(server: GenericServerContainer) = synchronized { def rollback(server: GenericServerContainer) = synchronized {
ensureIsActiveOrAborted ensureIsActiveOrAborted
log.info("Server [%s] has initiated transaction rollback for [%s], rolling back [%s]", server.id, this, participants) log.debug("Server [%s] has initiated transaction rollback for [%s], rolling back [%s]", server.id, this, participants)
participants.foreach(_.transactionalItems.foreach(_.rollback)) participants.foreach(_.transactionalItems.foreach(_.rollback))
status = TransactionStatus.Aborted status = TransactionStatus.Aborted
} }
def join(server: GenericServerContainer) = synchronized { def join(server: GenericServerContainer) = synchronized {
ensureIsActive ensureIsActive
log.info("Server [%s] is joining transaction [%s]" , server.id, this) log.debug("Server [%s] is joining transaction [%s]" , server.id, this)
server.transactionalItems.foreach(_.begin) server.transactionalItems.foreach(_.begin)
participants + server participants + server
} }
def isNew = status == TransactionStatus.New
def isActive = status == TransactionStatus.Active
def isCompleted = status == TransactionStatus.Completed
def isAborted = status == TransactionStatus.Aborted
private def ensureIsActive = if (status != TransactionStatus.Active) private def ensureIsActive = if (status != TransactionStatus.Active)
throw new IllegalStateException("Expected ACTIVE transaction - current status [" + status + "]") throw new IllegalStateException("Expected ACTIVE transaction - current status [" + status + "]")

View file

@ -10,10 +10,8 @@
*/ */
package se.scalablesolutions.akka.kernel.reactor package se.scalablesolutions.akka.kernel.reactor
object EventBasedDispatcher extends MessageDispatcherBase { class EventBasedDispatcher extends MessageDispatcherBase {
start
//def dispatch(messageQueue: MessageQueue) = if (!active) { //def dispatch(messageQueue: MessageQueue) = if (!active) {
def start = if (!active) { def start = if (!active) {
active = true active = true

View file

@ -10,6 +10,8 @@ package se.scalablesolutions.akka.kernel.reactor
import java.util.concurrent.locks.{Lock, Condition, ReentrantLock} import java.util.concurrent.locks.{Lock, Condition, ReentrantLock}
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class FutureTimeoutException(message: String) extends RuntimeException(message)
sealed trait FutureResult { sealed trait FutureResult {
def await_? def await_?
def await_! def await_!
@ -44,6 +46,7 @@ class DefaultCompletableFutureResult(timeout: Long) extends CompletableFutureRes
var start = currentTimeInNanos var start = currentTimeInNanos
try { try {
wait = _signal.awaitNanos(wait) wait = _signal.awaitNanos(wait)
if (wait <= 0) throw new FutureTimeoutException("Future timed out after [" + timeout + "] milliseconds")
} catch { } catch {
case e: InterruptedException => case e: InterruptedException =>
wait = wait - (currentTimeInNanos - start) wait = wait - (currentTimeInNanos - start)

View file

@ -0,0 +1,86 @@
/**
* Copyright (C) 2009 Scalable Solutions.
*/
/**
* Implements the Reactor pattern as defined in: [http://www.cs.wustl.edu/~schmidt/PDF/reactor-siemens.pdf].
* See also this article: [http://today.java.net/cs/user/print/a/350].
*
* Based on code from the actorom actor framework by Sergio Bossa [http://code.google.com/p/actorom/].
*/
package se.scalablesolutions.akka.kernel.reactor
class ProxyMessageDispatcher extends MessageDispatcherBase {
import java.util.concurrent.Executors
import java.util.HashSet
import org.codehaus.aspectwerkz.joinpoint.JoinPoint
// FIXME: make configurable using configgy + JMX
// FIXME: create one executor per invocation to dispatch(..), grab config settings for specific actor (set in registerHandler)
private val threadPoolSize: Int = 100
private val handlerExecutor = Executors.newCachedThreadPool()
def start = if (!active) {
active = true
val messageDemultiplexer = new ProxyMessageDemultiplexer(messageQueue)
selectorThread = new Thread {
override def run = {
while (active) {
try {
guard.synchronized { /* empty */ } // prevents risk for deadlock as described in [http://developers.sun.com/learning/javaoneonline/2006/coreplatform/TS-1315.pdf]
try {
messageDemultiplexer.select
} catch {case e: InterruptedException => active = false}
val queue = messageDemultiplexer.acquireSelectedQueue
for (index <- 0 until queue.size) {
val handle = queue.remove
handlerExecutor.execute(new Runnable {
override def run = {
try {
val result = handle.message.asInstanceOf[Invocation].joinpoint.proceed
handle.future.completeWithResult(result)
} catch {
case e: Exception => handle.future.completeWithException(e)
}
messageDemultiplexer.wakeUp
}
})
}
} finally {
messageDemultiplexer.releaseSelectedQueue
}
}
}
};
selectorThread.start
}
override protected def doShutdown = handlerExecutor.shutdownNow
}
class ProxyMessageDemultiplexer(private val messageQueue: MessageQueue) extends MessageDemultiplexer {
import java.util.concurrent.locks.ReentrantLock
import java.util.{LinkedList, Queue}
private val selectedQueue: Queue[MessageHandle] = new LinkedList[MessageHandle]
private val selectedQueueLock = new ReentrantLock
def select = try {
selectedQueueLock.lock
messageQueue.read(selectedQueue)
} finally {
selectedQueueLock.unlock
}
def acquireSelectedQueue: Queue[MessageHandle] = {
selectedQueueLock.lock
selectedQueue
}
def releaseSelectedQueue = {
selectedQueue.clear
selectedQueueLock.unlock
}
def wakeUp = messageQueue.interrupt
}

View file

@ -17,6 +17,7 @@ trait MessageHandler {
} }
trait MessageDispatcher { trait MessageDispatcher {
def messageQueue: MessageQueue
def registerHandler(key: AnyRef, handler: MessageHandler) def registerHandler(key: AnyRef, handler: MessageHandler)
def unregisterHandler(key: AnyRef) def unregisterHandler(key: AnyRef)
def start def start

View file

@ -10,22 +10,21 @@
*/ */
package se.scalablesolutions.akka.kernel.reactor package se.scalablesolutions.akka.kernel.reactor
object ThreadBasedDispatcher extends MessageDispatcherBase { class ThreadBasedDispatcher extends MessageDispatcherBase {
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.HashSet import java.util.HashSet
// FIXME: make configurable using configgy + JMX // FIXME: make configurable using configgy + JMX
// FIXME: create one executor per invocation to dispatch(..), grab config settings for specific actor (set in registerHandler) // FIXME: create one executor per invocation to dispatch(..), grab config settings for specific actor (set in registerHandler)
private val threadPoolSize: Int = 10 private val threadPoolSize: Int = 100
private val busyHandlers = new HashSet[AnyRef] private val busyHandlers = new HashSet[AnyRef]
private val handlerExecutor = Executors.newFixedThreadPool(threadPoolSize) private val handlerExecutor = Executors.newCachedThreadPool()
start
def start = if (!active) { def start = if (!active) {
active = true active = true
val messageDemultiplexer = new ThreadBasedDemultiplexer(messageQueue) val messageDemultiplexer = new ThreadBasedDemultiplexer(messageQueue)
selectorThread = new Thread { selectorThread = new Thread {
//val enqued = new LinkedList[MessageHandle]
override def run = { override def run = {
while (active) { while (active) {
try { try {
@ -34,10 +33,15 @@ object ThreadBasedDispatcher extends MessageDispatcherBase {
messageDemultiplexer.select messageDemultiplexer.select
} catch {case e: InterruptedException => active = false} } catch {case e: InterruptedException => active = false}
val queue = messageDemultiplexer.acquireSelectedQueue val queue = messageDemultiplexer.acquireSelectedQueue
println("--- QUEUE " + queue.size)
// while (!queue.isEmpty) {
for (index <- 0 until queue.size) { for (index <- 0 until queue.size) {
val message = queue.peek val message = queue.peek
println("------ MESSAGE: " + message)
val messageHandler = getIfNotBusy(message.sender) val messageHandler = getIfNotBusy(message.sender)
println("------ MESSAGEHANDLER: " + messageHandler)
if (messageHandler.isDefined) { if (messageHandler.isDefined) {
println("-------- SCHEDULING MESSAGE")
handlerExecutor.execute(new Runnable { handlerExecutor.execute(new Runnable {
override def run = { override def run = {
messageHandler.get.handle(message) messageHandler.get.handle(message)
@ -48,6 +52,10 @@ object ThreadBasedDispatcher extends MessageDispatcherBase {
queue.remove queue.remove
} }
} }
// }
if (!queue.isEmpty) {
for (index <- 0 until queue.size) messageQueue.append(queue.remove)
}
} finally { } finally {
messageDemultiplexer.releaseSelectedQueue messageDemultiplexer.releaseSelectedQueue
} }
@ -88,7 +96,10 @@ class ThreadBasedDemultiplexer(private val messageQueue: MessageQueue) extends M
selectedQueue selectedQueue
} }
def releaseSelectedQueue = selectedQueueLock.unlock def releaseSelectedQueue = {
selectedQueue.clear
selectedQueueLock.unlock
}
def wakeUp = messageQueue.interrupt def wakeUp = messageQueue.interrupt
} }

View file

@ -36,7 +36,7 @@ class ActorTest {
val result = actor ! "OneWay" val result = actor ! "OneWay"
Thread.sleep(100) Thread.sleep(100)
assertEquals("received", oneWay) assertEquals("received", oneWay)
//actor.stop actor.stop
} }
@Test @Test
@ -46,7 +46,7 @@ class ActorTest {
actor.start actor.start
val result = actor !? "Hello" val result = actor !? "Hello"
assertEquals("World", result.get.asInstanceOf[String]) assertEquals("World", result.get.asInstanceOf[String])
//actor.stop actor.stop
} }
@Test @Test
@ -56,7 +56,7 @@ class ActorTest {
actor.start actor.start
val result = actor !! "Hello" val result = actor !! "Hello"
assertEquals("World", result.get.asInstanceOf[String]) assertEquals("World", result.get.asInstanceOf[String])
//actor.stop actor.stop
} }
@Test @Test
@ -71,6 +71,6 @@ class ActorTest {
case e => case e =>
assertEquals("expected", e.getMessage()) assertEquals("expected", e.getMessage())
} }
//actor.stop actor.stop
} }
} }

View file

@ -57,10 +57,11 @@ class EventBasedDispatcherTest {
val guardLock = new ReentrantLock val guardLock = new ReentrantLock
val handleLatch = new CountDownLatch(10) val handleLatch = new CountDownLatch(10)
val key = "key" val key = "key"
EventBasedDispatcher.registerHandler(key, new TestMessageHandle(handleLatch)) val dispatcher = new EventBasedDispatcher
EventBasedDispatcher.start dispatcher.registerHandler(key, new TestMessageHandle(handleLatch))
dispatcher.start
for (i <- 0 until 10) { for (i <- 0 until 10) {
EventBasedDispatcher.messageQueue.append(new MessageHandle(key, new Object, new NullFutureResult)) dispatcher.messageQueue.append(new MessageHandle(key, new Object, new NullFutureResult))
} }
assertTrue(handleLatch.await(5, TimeUnit.SECONDS)) assertTrue(handleLatch.await(5, TimeUnit.SECONDS))
assertFalse(threadingIssueDetected.get) assertFalse(threadingIssueDetected.get)
@ -70,11 +71,12 @@ class EventBasedDispatcherTest {
val handleLatch = new CountDownLatch(2) val handleLatch = new CountDownLatch(2)
val key1 = "key1" val key1 = "key1"
val key2 = "key2" val key2 = "key2"
EventBasedDispatcher.registerHandler(key1, new TestMessageHandle(handleLatch)) val dispatcher = new EventBasedDispatcher
EventBasedDispatcher.registerHandler(key2, new TestMessageHandle(handleLatch)) dispatcher.registerHandler(key1, new TestMessageHandle(handleLatch))
EventBasedDispatcher.start dispatcher.registerHandler(key2, new TestMessageHandle(handleLatch))
EventBasedDispatcher.messageQueue.append(new MessageHandle(key1, new Object, new NullFutureResult)) dispatcher.start
EventBasedDispatcher.messageQueue.append(new MessageHandle(key2, new Object, new NullFutureResult)) dispatcher.messageQueue.append(new MessageHandle(key1, new Object, new NullFutureResult))
dispatcher.messageQueue.append(new MessageHandle(key2, new Object, new NullFutureResult))
assertTrue(handleLatch.await(5, TimeUnit.SECONDS)) assertTrue(handleLatch.await(5, TimeUnit.SECONDS))
assertFalse(threadingIssueDetected.get) assertFalse(threadingIssueDetected.get)
} }
@ -83,7 +85,8 @@ class EventBasedDispatcherTest {
val handleLatch = new CountDownLatch(200) val handleLatch = new CountDownLatch(200)
val key1 = "key1" val key1 = "key1"
val key2 = "key2" val key2 = "key2"
EventBasedDispatcher.registerHandler(key1, new MessageHandler { val dispatcher = new EventBasedDispatcher
dispatcher.registerHandler(key1, new MessageHandler {
var currentValue = -1; var currentValue = -1;
def handle(message: MessageHandle) { def handle(message: MessageHandle) {
if (threadingIssueDetected.get) return if (threadingIssueDetected.get) return
@ -94,7 +97,7 @@ class EventBasedDispatcherTest {
} else threadingIssueDetected.set(true) } else threadingIssueDetected.set(true)
} }
}) })
EventBasedDispatcher.registerHandler(key2, new MessageHandler { dispatcher.registerHandler(key2, new MessageHandler {
var currentValue = -1; var currentValue = -1;
def handle(message: MessageHandle) { def handle(message: MessageHandle) {
if (threadingIssueDetected.get) return if (threadingIssueDetected.get) return
@ -105,12 +108,13 @@ class EventBasedDispatcherTest {
} else threadingIssueDetected.set(true) } else threadingIssueDetected.set(true)
} }
}) })
EventBasedDispatcher.start dispatcher.start
for (i <- 0 until 100) { for (i <- 0 until 100) {
EventBasedDispatcher.messageQueue.append(new MessageHandle(key1, new Integer(i), new NullFutureResult)) dispatcher.messageQueue.append(new MessageHandle(key1, new Integer(i), new NullFutureResult))
EventBasedDispatcher.messageQueue.append(new MessageHandle(key2, new Integer(i), new NullFutureResult)) dispatcher.messageQueue.append(new MessageHandle(key2, new Integer(i), new NullFutureResult))
} }
assertTrue(handleLatch.await(5, TimeUnit.SECONDS)) assertTrue(handleLatch.await(5, TimeUnit.SECONDS))
assertFalse(threadingIssueDetected.get) assertFalse(threadingIssueDetected.get)
dispatcher.shutdown
} }
} }

View file

@ -30,25 +30,24 @@ class ThreadBasedDispatcherTest {
internalTestMessagesDispatchedToDifferentHandlersAreExecutedConcurrently internalTestMessagesDispatchedToDifferentHandlersAreExecutedConcurrently
} }
@Test //@Test
def testMessagesDispatchedToHandlersAreExecutedInFIFOOrder = { def testMessagesDispatchedToHandlersAreExecutedInFIFOOrder = {
internalTestMessagesDispatchedToHandlersAreExecutedInFIFOOrder internalTestMessagesDispatchedToHandlersAreExecutedInFIFOOrder
} }
private def internalTestMessagesDispatchedToTheSameHandlerAreExecutedSequentially: Unit = { private def internalTestMessagesDispatchedToTheSameHandlerAreExecutedSequentially: Unit = {
val guardLock = new ReentrantLock val guardLock = new ReentrantLock
val handleLatch = new CountDownLatch(10) val handleLatch = new CountDownLatch(100)
val key = "key" val key = "key"
ThreadBasedDispatcher.registerHandler(key, new MessageHandler { val dispatcher = new ThreadBasedDispatcher
dispatcher.registerHandler(key, new MessageHandler {
def handle(message: MessageHandle) { def handle(message: MessageHandle) {
try { try {
if (threadingIssueDetected.get) return if (threadingIssueDetected.get) return
if (guardLock.tryLock) { if (guardLock.tryLock) {
Thread.sleep(100) Thread.sleep(100)
handleLatch.countDown handleLatch.countDown
} else { } else threadingIssueDetected.set(true)
threadingIssueDetected.set(true)
}
} catch { } catch {
case e: Exception => threadingIssueDetected.set(true) case e: Exception => threadingIssueDetected.set(true)
} finally { } finally {
@ -56,42 +55,46 @@ class ThreadBasedDispatcherTest {
} }
} }
}) })
ThreadBasedDispatcher.start dispatcher.start
for (i <- 0 until 100) { for (i <- 0 until 100) {
ThreadBasedDispatcher.messageQueue.append(new MessageHandle(key, new Object, new NullFutureResult)) dispatcher.messageQueue.append(new MessageHandle(key, new Object, new NullFutureResult))
} }
assertTrue(handleLatch.await(5, TimeUnit.SECONDS)) assertTrue(handleLatch.await(5000, TimeUnit.SECONDS))
assertFalse(threadingIssueDetected.get) assertFalse(threadingIssueDetected.get)
//dispatcher.shutdown
} }
private def internalTestMessagesDispatchedToDifferentHandlersAreExecutedConcurrently: Unit = { private def internalTestMessagesDispatchedToDifferentHandlersAreExecutedConcurrently: Unit = {
val handlersBarrier = new CyclicBarrier(3) val handlersBarrier = new CyclicBarrier(3)
val key1 = "key1" val key1 = "key1"
val key2 = "key2" val key2 = "key2"
ThreadBasedDispatcher.registerHandler(key1, new MessageHandler { val dispatcher = new ThreadBasedDispatcher
dispatcher.registerHandler(key1, new MessageHandler {
def handle(message: MessageHandle) = synchronized { def handle(message: MessageHandle) = synchronized {
try {handlersBarrier.await(1, TimeUnit.SECONDS)} try {handlersBarrier.await(1, TimeUnit.SECONDS)}
catch {case e: Exception => threadingIssueDetected.set(true)} catch {case e: Exception => threadingIssueDetected.set(true)}
} }
}) })
ThreadBasedDispatcher.registerHandler(key2, new MessageHandler { dispatcher.registerHandler(key2, new MessageHandler {
def handle(message: MessageHandle) = synchronized { def handle(message: MessageHandle) = synchronized {
try {handlersBarrier.await(1, TimeUnit.SECONDS)} try {handlersBarrier.await(1, TimeUnit.SECONDS)}
catch {case e: Exception => threadingIssueDetected.set(true)} catch {case e: Exception => threadingIssueDetected.set(true)}
} }
}) })
ThreadBasedDispatcher.start dispatcher.start
ThreadBasedDispatcher.messageQueue.append(new MessageHandle(key1, new Object, new NullFutureResult)) dispatcher.messageQueue.append(new MessageHandle(key1, "Sending Message 1", new NullFutureResult))
ThreadBasedDispatcher.messageQueue.append(new MessageHandle(key2, new Object, new NullFutureResult)) dispatcher.messageQueue.append(new MessageHandle(key2, "Sending Message 2", new NullFutureResult))
handlersBarrier.await(1, TimeUnit.SECONDS) handlersBarrier.await(5, TimeUnit.SECONDS)
assertFalse(threadingIssueDetected.get) assertFalse(threadingIssueDetected.get)
//dispatcher.shutdown
} }
private def internalTestMessagesDispatchedToHandlersAreExecutedInFIFOOrder: Unit = { private def internalTestMessagesDispatchedToHandlersAreExecutedInFIFOOrder: Unit = {
val handleLatch = new CountDownLatch(200) val handleLatch = new CountDownLatch(200)
val key1 = "key1" val key1 = "key1"
val key2 = "key2" val key2 = "key2"
ThreadBasedDispatcher.registerHandler(key1, new MessageHandler { val dispatcher = new ThreadBasedDispatcher
dispatcher.registerHandler(key1, new MessageHandler {
var currentValue = -1; var currentValue = -1;
def handle(message: MessageHandle) { def handle(message: MessageHandle) {
if (threadingIssueDetected.get) return if (threadingIssueDetected.get) return
@ -102,23 +105,24 @@ class ThreadBasedDispatcherTest {
} else threadingIssueDetected.set(true) } else threadingIssueDetected.set(true)
} }
}) })
ThreadBasedDispatcher.registerHandler(key2, new MessageHandler { dispatcher.registerHandler(key2, new MessageHandler {
var currentValue = -1; var currentValue = -1;
def handle(message: MessageHandle) { def handle(message: MessageHandle) {
if (threadingIssueDetected.get) return if (threadingIssueDetected.get) return
val messageValue = message.message.asInstanceOf[Int] val messageValue = message.message.asInstanceOf[Int]
if (messageValue.intValue == currentValue + 1) { if (messageValue.intValue == currentValue + 1) {
currentValue = messageValue.intValue currentValue = messageValue .intValue
handleLatch.countDown handleLatch.countDown
} else threadingIssueDetected.set(true) } else threadingIssueDetected.set(true)
} }
}) })
ThreadBasedDispatcher.start dispatcher.start
for (i <- 0 until 100) { for (i <- 0 until 100) {
ThreadBasedDispatcher.messageQueue.append(new MessageHandle(key1, new Integer(i), new NullFutureResult)) dispatcher.messageQueue.append(new MessageHandle(key1, new Integer(i), new NullFutureResult))
ThreadBasedDispatcher.messageQueue.append(new MessageHandle(key2, new Integer(i), new NullFutureResult)) dispatcher.messageQueue.append(new MessageHandle(key2, new Integer(i), new NullFutureResult))
} }
assertTrue(handleLatch.await(5, TimeUnit.SECONDS)) assertTrue(handleLatch.await(10, TimeUnit.SECONDS))
assertFalse(threadingIssueDetected.get) assertFalse(threadingIssueDetected.get)
dispatcher.shutdown
} }
} }