merge with multiverse stm branch

This commit is contained in:
jboner 2009-08-16 00:35:11 +02:00
commit ae9c93d689
21 changed files with 1503 additions and 666 deletions

0
LICENSE Normal file → Executable file
View file

0
README.textile Normal file → Executable file
View file

0
akka.iml Normal file → Executable file
View file

0
akka.ipr Normal file → Executable file
View file

651
akka.iws Normal file → Executable file
View file

@ -7,14 +7,23 @@
<component name="ChangeListManager">
<list readonly="true" id="6e842704-fac6-40e9-8a67-d02385f87db9" 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" id="212ccd86-01aa-4780-a2f0-0d130be5abd2" name="Test" comment="Test">
<change type="MOVED" beforePath="C:\home\jboner\src\scala\akka\kernel\src\main\scala\jersey\ActorComponentProviderFactory.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/rest/ActorComponentProviderFactory.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/deploy/root/META-INF/atmosphere.xml" afterPath="$PROJECT_DIR$/deploy/root/META-INF/atmosphere.xml" />
<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$/samples-lift/src/main/webapp/WEB-INF/web.xml" afterPath="$PROJECT_DIR$/samples-lift/src/main/webapp/WEB-INF/web.xml" />
<change type="MOVED" beforePath="C:\home\jboner\src\scala\akka\kernel\src\main\scala\jersey\AkkaServlet.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/rest/AkkaServlet.scala" />
<change type="MOVED" beforePath="C:\home\jboner\src\scala\akka\kernel\src\main\scala\jersey\ActorComponentProvider.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/rest/ActorComponentProvider.scala" />
<change type="MOVED" beforePath="C:\home\jboner\src\scala\akka\kernel\src\main\scala\jersey\NodeWriter.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/rest/NodeWriter.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/util-java/pom.xml" afterPath="$PROJECT_DIR$/util-java/pom.xml" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/actor/Actor.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/actor/Actor.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/LICENSE" afterPath="$PROJECT_DIR$/LICENSE" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/nio/RemoteServer.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/nio/RemoteServer.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/stm/TransactionManagement.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/stm/TransactionManagement.scala" />
<change type="DELETED" beforePath="C:\home\jboner\src\scala\akka\kernel\src\main\scala\state\State.scala" afterPath="" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/test/scala/TransactionClasherSpec.scala" afterPath="$PROJECT_DIR$/kernel/src/test/scala/TransactionClasherSpec.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/main/scala/stm/Transaction.scala" afterPath="$PROJECT_DIR$/kernel/src/main/scala/stm/Transaction.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/akka.ipr" afterPath="$PROJECT_DIR$/akka.ipr" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/README.textile" afterPath="$PROJECT_DIR$/README.textile" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/buildfile" afterPath="$PROJECT_DIR$/buildfile" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/src/test/scala/InMemoryActorSpec.scala" afterPath="$PROJECT_DIR$/kernel/src/test/scala/InMemoryActorSpec.scala" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/akka.iml" afterPath="$PROJECT_DIR$/akka.iml" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/embedded-repo/org/multiverse/multiverse/0.3/multiverse-0.3.jar" afterPath="$PROJECT_DIR$/embedded-repo/org/multiverse/multiverse/0.3/multiverse-0.3.jar" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/pom.xml" afterPath="$PROJECT_DIR$/pom.xml" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/akka.iws" afterPath="$PROJECT_DIR$/akka.iws" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/kernel/pom.xml" afterPath="$PROJECT_DIR$/kernel/pom.xml" />
</list>
<ignored path=".idea/workspace.xml" />
<ignored path="akka.iws" />
@ -33,6 +42,60 @@
<disable_hints />
</component>
<component name="DebuggerManager">
<line_breakpoints>
<breakpoint url="file://$PROJECT_DIR$/kernel/src/main/scala/serialization/Binary.scala" line="6" class="Class at Binary.scala:6" 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/reactor/MessageDispatcherBase.scala" line="23" class="Class at MessageDispatcherBase.scala:23" 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/serialization/Serializer.scala" line="36" class="Class at Serializer.scala:36" 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/Kernel.scala" line="126" class="Class at Kernel.scala:126" 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>
</line_breakpoints>
<breakpoint_any>
<breakpoint>
<option name="NOTIFY_CAUGHT" value="true" />
@ -80,8 +143,8 @@
<property name="field_breakpoints_groupByClasses" value="true" />
<property name="method_breakpoints_groupByClasses" value="true" />
<property name="exception_breakpoints_viewId" value="TABLE" />
<property name="field_breakpoints_viewId" value="TABLE" />
<property name="exception_breakpoints_groupByClasses" value="true" />
<property name="field_breakpoints_viewId" value="TABLE" />
<property name="method_breakpoints_groupByMethods" value="false" />
</ui_properties>
</component>
@ -95,37 +158,46 @@
<component name="FileColors" enabled="false" enabledForTabs="false" />
<component name="FileEditorManager">
<leaf>
<file leaf-file-name="ActorComponentProvider.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/rest/ActorComponentProvider.scala">
<file leaf-file-name="CassandraStorage.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/state/CassandraStorage.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="4" column="45" selection-start="96" selection-end="96" vertical-scroll-proportion="0.0">
<state line="22" column="0" selection-start="0" selection-end="470" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="ActorComponentProviderFactory.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/rest/ActorComponentProviderFactory.scala">
<file leaf-file-name="CassandraSession.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/state/CassandraSession.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="4" column="45" selection-start="96" selection-end="96" vertical-scroll-proportion="0.0">
<state line="22" column="6" selection-start="476" selection-end="476" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="AkkaServlet.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/rest/AkkaServlet.scala">
<file leaf-file-name="SimpleService.java" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/samples-java/src/main/java/sample/java/SimpleService.java">
<provider selected="true" editor-type-id="text-editor">
<state line="31" column="6" selection-start="919" selection-end="919" vertical-scroll-proportion="0.0">
<state line="31" column="33" selection-start="971" selection-end="971" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="NodeWriter.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/rest/NodeWriter.scala">
<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="4" column="45" selection-start="96" selection-end="96" vertical-scroll-proportion="0.0">
<state line="19" column="42" selection-start="764" selection-end="764" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="PersistentActorSpec.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/test/scala/PersistentActorSpec.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="101" column="6" selection-start="3487" selection-end="3487" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
@ -134,16 +206,25 @@
<file leaf-file-name="Kernel.scala" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/Kernel.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="171" column="20" selection-start="7802" selection-end="7802" vertical-scroll-proportion="0.0">
<state line="14" column="77" selection-start="408" selection-end="408" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="Messages.scala" pinned="false" current="true" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/kernel/src/test/scala/Messages.scala">
<file leaf-file-name="pom.xml" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/pom.xml">
<provider selected="true" editor-type-id="text-editor">
<state line="22" column="68" selection-start="737" selection-end="737" vertical-scroll-proportion="0.34552845">
<state line="55" column="20" selection-start="1626" selection-end="1626" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="pom.xml" pinned="false" current="true" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/fun-test-java/pom.xml">
<provider selected="true" editor-type-id="text-editor">
<state line="87" column="0" selection-start="2607" selection-end="2607" vertical-scroll-proportion="0.4644309">
<folding />
</state>
</provider>
@ -162,22 +243,22 @@
<component name="IdeDocumentHistory">
<option name="changedFiles">
<list>
<option value="$PROJECT_DIR$/samples-scala/src/main/scala/SimpleService.scala" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/Boot.scala" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/actor/ActiveObject.scala" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/serialization/Serializer.scala" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/util/Helpers.scala" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/state/State.scala" />
<option value="$PROJECT_DIR$/kernel/pom.xml" />
<option value="$PROJECT_DIR$/pom.xml" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/state/Pool.scala" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/Kernel.scala" />
<option value="$PROJECT_DIR$/config/akka-reference.conf" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/state/CassandraStorage.scala" />
<option value="$PROJECT_DIR$/fun-test-java/src/test/java/se/scalablesolutions/akka/api/PersistentStateful.java" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/state/CassandraSession.scala" />
<option value="$PROJECT_DIR$/samples-java/src/main/java/sample/java/SimpleService.java" />
<option value="$PROJECT_DIR$/fun-test-java/pom.xml" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/rest/ActorComponentProvider.scala" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/rest/ActorComponentProviderFactory.scala" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/rest/AkkaServlet.scala" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/rest/NodeWriter.scala" />
<option value="$PROJECT_DIR$/kernel/src/main/scala/Kernel.scala" />
</list>
</option>
</component>
@ -248,6 +329,118 @@
<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-samples-scala" />
<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-samples-scala" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="samples-scala" />
<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>
<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-samples-java" />
<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-samples-java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="samples-java" />
<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-samples-java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="samples-java" />
<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="java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="SimpleService" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ClassTreeNode" />
</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-samples-java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="samples-java" />
<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="java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
@ -258,6 +451,132 @@
<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>
<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.apache.cassandra:cassandra:0.4.0-dev" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="cassandra-0.4.0-dev.jar" />
<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="Libraries" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.LibraryGroupNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Maven: org.apache.cassandra:cassandra:0.4.0-dev" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="cassandra-0.4.0-dev.jar" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="service" />
<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="Libraries" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.LibraryGroupNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Maven: org.apache.cassandra:cassandra:0.4.0-dev" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="cassandra-0.4.0-dev.jar" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="service" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Cassandra" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ClassTreeNode" />
</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: commons-pool:commons-pool:1.5.1" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="commons-pool-1.5.1.jar" />
<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="Libraries" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.LibraryGroupNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Maven: com.facebook:thrift:1.0" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="thrift-1.0.jar" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
@ -351,7 +670,37 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="rest" />
<option name="myItemId" value="util" />
<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="state" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
@ -377,6 +726,94 @@
<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-fun-test-java" />
<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-fun-test-java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="fun-test-java" />
<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-fun-test-java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="fun-test-java" />
<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="test" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="api" />
<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-fun-test-java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="fun-test-java" />
<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="test" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="api" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="PersistentStateful" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ClassTreeNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="akka" />
@ -386,6 +823,14 @@
<option name="myItemId" value="akka" />
<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="&lt; 1.6 &gt;" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
@ -452,9 +897,9 @@
<property name="GoToClass.toSaveIncludeLibraries" value="false" />
<property name="MemberChooser.showClasses" value="true" />
<property name="GoToClass.includeLibraries" value="false" />
<property name="dynamic.classpath" value="false" />
<property name="options.splitter.details.proportions" value="0.2" />
<property name="options.searchVisible" value="true" />
<property name="options.splitter.details.proportions" value="0.2" />
<property name="dynamic.classpath" value="false" />
</component>
<component name="RecentsManager">
<key name="CopyClassDialog.RECENTS_KEY">
@ -468,7 +913,7 @@
<recent name="stm" />
</key>
</component>
<component name="RunManager">
<component name="RunManager" selected="Unknown.InMemoryStateTest">
<configuration default="false" name="PersistentActorSpec.testMapShouldNotRollbackStateForStatefulServerInCaseOfSuccess" type="JUnit" factoryName="JUnit" temporary="true" enabled="false" merge="false" sample_coverage="true" runner="emma">
<pattern>
<option name="PATTERN" value="se.scalablesolutions.akka.kernel.actor.*" />
@ -845,17 +1290,6 @@
<option name="Maven.BeforeRunTask" enabled="false" />
</method>
</configuration>
<configuration default="false" name="Scala Console" type="ScalaScriptConsoleRunConfiguration" factoryName="Scala Console">
<module name="" />
<setting name="vmparams" value="" />
<setting name="consoleArgs" value="" />
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Run" />
<method>
<option name="AntTarget" enabled="false" />
<option name="Make" enabled="false" />
</method>
</configuration>
<configuration default="false" name="CamelSpec" 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" />
@ -1448,10 +1882,21 @@
<option name="Make" enabled="false" />
</method>
</configuration>
<configuration default="false" name="Scala Console" type="ScalaScriptConsoleRunConfiguration" factoryName="Scala Console">
<module name="" />
<setting name="vmparams" value="" />
<setting name="consoleArgs" value="" />
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Run" />
<method>
<option name="AntTarget" enabled="false" />
<option name="Make" enabled="false" />
</method>
</configuration>
<list size="3">
<item index="0" class="java.lang.String" itemvalue="Scala Console.Scala Console" />
<item index="1" class="java.lang.String" itemvalue="Application.Kernel" />
<item index="2" class="java.lang.String" itemvalue="Remote.Unnamed" />
<item index="0" class="java.lang.String" itemvalue="Application.Kernel" />
<item index="1" class="java.lang.String" itemvalue="Remote.Unnamed" />
<item index="2" class="java.lang.String" itemvalue="Scala Console.Scala Console" />
</list>
<configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false">
<Host>localhost</Host>
@ -1534,10 +1979,9 @@
<window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32749078" sideWeight="0.5" order="9" 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="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32749078" sideWeight="0.5" order="6" side_tool="false" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3188119" sideWeight="0.5" 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.24906267" sideWeight="0.5212177" 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.16818425" sideWeight="0.24354243" order="0" side_tool="true" x="1609" y="144" width="252" height="862" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.17424242" sideWeight="0.6742574" 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.17424242" sideWeight="0.6619898" order="1" 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="15" side_tool="false" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.39668366" sideWeight="0.5" order="3" side_tool="false" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.28316328" sideWeight="0.0" order="2" side_tool="false" x="4" y="22" width="1436" height="878" />
@ -1552,6 +1996,7 @@
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" 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="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="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.31887755" sideWeight="0.5" order="1" side_tool="false" />
<window_info id="FindBugs-IDEA" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32976654" 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.32908162" sideWeight="0.0" order="14" side_tool="false" />
<window_info id="Web" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.26479077" sideWeight="0.24617347" order="2" side_tool="true" />
@ -1595,16 +2040,46 @@
<option name="FILTER_TARGETS" value="false" />
</component>
<component name="editorHistoryManager">
<entry file="jar://$MAVEN_REPOSITORY$/net/lag/configgy/1.3/configgy-1.3.jar!/net/lag/configgy/ParseException.class">
<entry file="jar://$MAVEN_REPOSITORY$/com/facebook/thrift/1.0/thrift-1.0.jar!/org/apache/thrift/transport/TIOStreamTransport.class">
<provider selected="true" editor-type-id="text-editor">
<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/test/scala/PersistentActorSpec.scala">
<entry file="jar://$MAVEN_REPOSITORY$/com/facebook/thrift/1.0/thrift-1.0.jar!/org/apache/thrift/transport/TSocket.class">
<provider selected="true" editor-type-id="text-editor">
<state line="101" column="6" selection-start="3487" selection-end="3487" vertical-scroll-proportion="0.0" />
<state line="5" column="64" selection-start="216" selection-end="216" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/com/facebook/thrift/1.0/thrift-1.0.jar!/org/apache/thrift/protocol/TProtocol.class">
<provider selected="true" editor-type-id="text-editor">
<state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/com/facebook/thrift/1.0/thrift-1.0.jar!/org/apache/thrift/protocol/TBinaryProtocol.class">
<provider selected="true" editor-type-id="text-editor">
<state line="5" column="60" selection-start="211" selection-end="211" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/apache/cassandra/cassandra/0.4.0-dev/cassandra-0.4.0-dev.jar!/org/apache/cassandra/service/Cassandra.class">
<provider selected="true" editor-type-id="text-editor">
<state line="2686" column="57" selection-start="135796" selection-end="135796" vertical-scroll-proportion="0.4197031">
<folding />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/net/lag/configgy/1.3/configgy-1.3.jar!/net/lag/configgy/ParseException.class">
<provider selected="true" editor-type-id="text-editor">
<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$/config/akka-reference.conf">
@ -1614,17 +2089,16 @@
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/state/CassandraStorage.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="22" column="0" selection-start="0" selection-end="470" vertical-scroll-proportion="0.0" />
<state line="22" column="0" selection-start="0" selection-end="470" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/state/CassandraSession.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="22" column="6" selection-start="476" selection-end="476" vertical-scroll-proportion="0.0" />
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/state/State.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="39" column="6" selection-start="1032" selection-end="1032" vertical-scroll-proportion="0.0" />
<state line="22" column="6" selection-start="476" selection-end="476" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/samples-java/src/main/java/sample/java/SimpleService.java">
@ -1641,6 +2115,20 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/test/scala/PersistentActorSpec.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="101" column="6" selection-start="3487" selection-end="3487" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/Kernel.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="14" column="77" selection-start="408" selection-end="408" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/pom.xml">
<provider selected="true" editor-type-id="text-editor">
<state line="55" column="20" selection-start="1626" selection-end="1626" vertical-scroll-proportion="0.0">
@ -1650,49 +2138,7 @@
</entry>
<entry file="file://$PROJECT_DIR$/fun-test-java/pom.xml">
<provider selected="true" editor-type-id="text-editor">
<state line="87" column="0" selection-start="2599" selection-end="2599" vertical-scroll-proportion="0.6960651">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/rest/ActorComponentProvider.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="4" column="45" selection-start="96" selection-end="96" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/rest/ActorComponentProviderFactory.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="4" column="45" selection-start="96" selection-end="96" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/rest/AkkaServlet.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="31" column="6" selection-start="919" selection-end="919" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/rest/NodeWriter.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="4" column="45" selection-start="96" selection-end="96" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/main/scala/Kernel.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="171" column="20" selection-start="7802" selection-end="7802" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/kernel/src/test/scala/Messages.scala">
<provider selected="true" editor-type-id="text-editor">
<state line="22" column="68" selection-start="737" selection-end="737" vertical-scroll-proportion="0.34552845">
<state line="87" column="0" selection-start="2607" selection-end="2607" vertical-scroll-proportion="0.4644309">
<folding />
</state>
</provider>
@ -1795,4 +2241,3 @@
</option>
</component>
</project>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.multiverse</groupId>
<artifactId>multiverse</artifactId>
<version>0.3</version>
<packaging>jar</packaging>
</project>

5
kernel/pom.xml Normal file → Executable file
View file

@ -72,6 +72,11 @@
<artifactId>javautils</artifactId>
<version>2.7.4-0.1</version>
</dependency>
<dependency>
<groupId>org.multiverse</groupId>
<artifactId>multiverse</artifactId>
<version>0.3</version>
</dependency>
<!-- For Protocol/Serialization -->
<dependency>

14
kernel/src/main/scala/actor/Actor.scala Normal file → Executable file
View file

@ -19,6 +19,7 @@ import nio.{RemoteProtocolBuilder, RemoteClient, RemoteServer, RemoteRequestIdFa
import management.Management
import com.twitter.service.Stats
import org.multiverse.utils.TransactionThreadLocal._
sealed abstract class LifecycleMessage
case class Init(config: AnyRef) extends LifecycleMessage
@ -464,7 +465,10 @@ trait Actor extends Logging with TransactionManagement {
}
private def dispatch[T](messageHandle: MessageInvocation) = {
if (messageHandle.tx.isDefined) TransactionManagement.threadBoundTx.set(messageHandle.tx)
if (messageHandle.tx.isDefined) {
TransactionManagement.threadBoundTx.set(messageHandle.tx)
setThreadLocalTransaction(messageHandle.tx.get.transaction)
}
val message = messageHandle.message //serializeMessage(messageHandle.message)
val future = messageHandle.future
try {
@ -479,11 +483,15 @@ trait Actor extends Logging with TransactionManagement {
else e.printStackTrace
} finally {
TransactionManagement.threadBoundTx.set(None)
setThreadLocalTransaction(null)
}
}
private def transactionalDispatch[T](messageHandle: MessageInvocation) = {
if (messageHandle.tx.isDefined) TransactionManagement.threadBoundTx.set(messageHandle.tx)
if (messageHandle.tx.isDefined) {
TransactionManagement.threadBoundTx.set(messageHandle.tx)
setThreadLocalTransaction(messageHandle.tx.get.transaction)
}
val message = messageHandle.message //serializeMessage(messageHandle.message)
val future = messageHandle.future
try {
@ -500,6 +508,7 @@ trait Actor extends Logging with TransactionManagement {
case e =>
rollback(activeTx)
TransactionManagement.threadBoundTx.set(None) // need to clear threadBoundTx before call to supervisor
setThreadLocalTransaction(null)
// FIXME to fix supervisor restart of remote actor for oneway calls, inject a supervisor proxy that can send notification back to client
if (supervisor.isDefined) supervisor.get ! Exit(this, e)
if (future.isDefined) future.get.completeWithException(this, e)
@ -510,6 +519,7 @@ trait Actor extends Logging with TransactionManagement {
else tryToPrecommitTransaction
rescheduleClashedMessages
TransactionManagement.threadBoundTx.set(None)
setThreadLocalTransaction(null)
}
}

6
kernel/src/main/scala/nio/RemoteServer.scala Normal file → Executable file
View file

@ -235,7 +235,11 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL
if (tx.isDefined) {
tx.get.reinit
TransactionManagement.threadBoundTx.set(tx)
} else TransactionManagement.threadBoundTx.set(None)
setThreadLocalTransaction(tx.transaction)
} else {
TransactionManagement.threadBoundTx.set(None)
setThreadLocalTransaction(null)
}
}
*/
private def unescapeArgs(args: scala.List[AnyRef], argClasses: scala.List[Class[_]], timeout: Long) = {

View file

@ -0,0 +1,61 @@
/**
* Copyright (C) 2009 Scalable Solutions.
*/
package se.scalablesolutions.akka.kernel.state
import kernel.stm.{Ref, TransactionManagement}
import akka.collection._
import org.codehaus.aspectwerkz.proxy.Uuid
import scala.collection.mutable.{ArrayBuffer, HashMap}
/**
* 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>
*/
class InMemoryTransactionalMap[K, V] extends TransactionalMap[K, V] {
protected[this] val ref = new TransactionalRef[HashTrie[K, V]](new HashTrie[K, V])
// ---- Overriding scala.collection.mutable.Map behavior ----
override def contains(key: K): Boolean = ref.get.get.contains(key)
override def clear = ref.swap(new HashTrie[K, V])
override def size: Int = ref.get.get.size
// ---- For scala.collection.mutable.Map ----
override def remove(key: K) = ref.swap(ref.get.get - key)
override def elements: Iterator[(K, V)] = ref.get.get.elements
override def get(key: K): Option[V] = ref.get.get.get(key)
override def put(key: K, value: V): Option[V] = {
val map = ref.get.get
val oldValue = map.get(key)
ref.swap(map.update(key, value))
oldValue
}
override def -=(key: K) = remove(key)
override def update(key: K, value: V) = put(key, value)
}
/**
* Implements an in-memory transactional vector.
*
* 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>
*/
class InMemoryTransactionalVector[T] extends TransactionalVector[T] {
private[kernel] val ref = new TransactionalRef[Vector[T]](EmptyVector)
def add(elem: T) = ref.swap(ref.get.get + elem)
def get(index: Int): T = ref.get.get.apply(index)
def getRange(start: Int, count: Int): List[T] = ref.get.get.slice(start, count).toList.asInstanceOf[List[T]]
// ---- For Seq ----
def length: Int = ref.get.get.length
def apply(index: Int): T = ref.get.get.apply(index)
override def elements: Iterator[T] = ref.get.get.elements
override def toList: List[T] = ref.get.get.toList
}

View file

@ -0,0 +1,269 @@
/**
* Copyright (C) 2009 Scalable Solutions.
*/
package se.scalablesolutions.akka.kernel.state
import kernel.stm.{Ref, TransactionManagement}
import akka.collection._
import org.codehaus.aspectwerkz.proxy.Uuid
import scala.collection.mutable.{ArrayBuffer, HashMap}
import org.multiverse.utils.TransactionThreadLocal._
/**
* Base class for all persistent transactional map 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 PersistentTransactionalMap[K, V] extends TransactionalMap[K, V] {
// FIXME: need to handle remove in another changeSet
protected[kernel] val changeSet = new HashMap[K, V]
def getRange(start: Option[AnyRef], count: Int)
// ---- For scala.collection.mutable.Map ----
override def put(key: K, value: V): Option[V] = {
verifyTransaction
changeSet += key -> value
None // always return None to speed up writes (else need to go to DB to get
}
override def -=(key: K) = remove(key)
override def update(key: K, value: V) = put(key, value)
}
/**
* Implementation of <tt>PersistentTransactionalMap</tt> for every concrete
* storage will have the same workflow. This abstracts the workflow.
*
* Subclasses just need to provide the actual concrete instance for the
* abstract val <tt>storage</tt>.
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
abstract class TemplatePersistentTransactionalMap extends PersistentTransactionalMap[AnyRef, AnyRef] {
// to be concretized in subclasses
val storage: MapStorage
override def remove(key: AnyRef) = {
if (changeSet.contains(key)) changeSet -= key
else storage.removeMapStorageFor(uuid, key)
}
override def getRange(start: Option[AnyRef], count: Int) =
getRange(start, None, count)
def getRange(start: Option[AnyRef], finish: Option[AnyRef], count: Int) = {
try {
storage.getMapStorageRangeFor(uuid, start, finish, count)
} catch {
case e: Exception => Nil
}
}
// ---- For Transactional ----
override def commit = {
storage.insertMapStorageEntriesFor(uuid, changeSet.toList)
changeSet.clear
}
// ---- Overriding scala.collection.mutable.Map behavior ----
override def clear = {
try {
storage.removeMapStorageFor(uuid)
} catch {
case e: Exception => {}
}
}
override def contains(key: AnyRef): Boolean = {
try {
verifyTransaction
storage.getMapStorageEntryFor(uuid, key).isDefined
} catch {
case e: Exception => false
}
}
override def size: Int = {
verifyTransaction
try {
storage.getMapStorageSizeFor(uuid)
} catch {
case e: Exception => 0
}
}
// ---- For scala.collection.mutable.Map ----
override def get(key: AnyRef): Option[AnyRef] = {
verifyTransaction
// if (changeSet.contains(key)) changeSet.get(key)
// else {
val result = try {
storage.getMapStorageEntryFor(uuid, key)
} catch {
case e: Exception => None
}
result
//}
}
override def elements: Iterator[Tuple2[AnyRef, AnyRef]] = {
//verifyTransaction
new Iterator[Tuple2[AnyRef, AnyRef]] {
private val originalList: List[Tuple2[AnyRef, AnyRef]] = try {
storage.getMapStorageFor(uuid)
} catch {
case e: Throwable => Nil
}
private var elements = originalList.reverse
override def next: Tuple2[AnyRef, AnyRef]= synchronized {
val element = elements.head
elements = elements.tail
element
}
override def hasNext: Boolean = synchronized { !elements.isEmpty }
}
}
}
/**
* Implements a persistent transactional map based on the Cassandra distributed P2P key-value storage.
*
* @author <a href="http://debasishg.blogspot.com">Debasish Ghosh</a>
*/
class CassandraPersistentTransactionalMap extends TemplatePersistentTransactionalMap {
val storage = CassandraStorage
}
/**
* Implements a persistent transactional map based on the MongoDB distributed P2P key-value storage.
*
* @author <a href="http://debasishg.blogspot.com">Debasish Ghosh</a>
*/
class MongoPersistentTransactionalMap extends TemplatePersistentTransactionalMap {
val storage = MongoStorage
}
/**
* 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] val changeSet = new ArrayBuffer[T]
// ---- For TransactionalVector ----
override def add(value: T) = {
verifyTransaction
changeSet += value
}
}
/**
* Implements a template for a concrete persistent transactional vector based storage.
*
* @author <a href="http://debasishg.blogspot.com">Debasish Ghosh</a>
*/
abstract class TemplatePersistentTransactionalVector extends PersistentTransactionalVector[AnyRef] {
val storage: VectorStorage
// ---- For TransactionalVector ----
override def get(index: Int): AnyRef = {
verifyTransaction
if (changeSet.size > index) changeSet(index)
else storage.getVectorStorageEntryFor(uuid, index)
}
override def getRange(start: Int, count: Int): List[AnyRef] =
getRange(Some(start), None, count)
def getRange(start: Option[Int], finish: Option[Int], count: Int): List[AnyRef] = {
verifyTransaction
storage.getVectorStorageRangeFor(uuid, start, finish, count)
}
override def length: Int = {
verifyTransaction
storage.getVectorStorageSizeFor(uuid)
}
override def apply(index: Int): AnyRef = get(index)
override def first: AnyRef = get(0)
override def last: AnyRef = {
verifyTransaction
val l = length
if (l == 0) throw new NoSuchElementException("Vector is empty")
get(length - 1)
}
override def commit = {
// FIXME: should use batch function once the bug is resolved
for (element <- changeSet) storage.insertVectorStorageEntryFor(uuid, element)
changeSet.clear
}
}
/**
* Implements a persistent transactional vector based on the Cassandra distributed P2P key-value storage.
*
* @author <a href="http://debasishg.blogspot.com">Debaissh Ghosh</a>
*/
class CassandraPersistentTransactionalVector extends TemplatePersistentTransactionalVector {
val storage = CassandraStorage
}
/**
* Implements a persistent transactional vector based on the MongoDB distributed P2P key-value storage.
*
* @author <a href="http://debasishg.blogspot.com">Debaissh Ghosh</a>
*/
class MongoPersistentTransactionalVector extends TemplatePersistentTransactionalVector {
val storage = MongoStorage
}
/**
* Implements a transactional reference.
*
* 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>
*/
class CassandraPersistentTransactionalRef extends TransactionalRef[AnyRef] {
override def commit = if (isDefined) {
CassandraStorage.insertRefStorageFor(uuid, ref.get)
ref.clear
}
override def get: Option[AnyRef] = {
verifyTransaction
if (isDefined) super.get
else CassandraStorage.getRefStorageFor(uuid)
}
override def isDefined: Boolean = get.isDefined
override def getOrElse(default: => AnyRef): AnyRef = {
val ref = get
if (ref.isDefined) ref.get
else default
}
}

View file

@ -1,548 +0,0 @@
/**
* Copyright (C) 2009 Scalable Solutions.
*/
package se.scalablesolutions.akka.kernel.state
import kernel.stm.TransactionManagement
import akka.collection._
import org.codehaus.aspectwerkz.proxy.Uuid
import scala.collection.mutable.{ArrayBuffer, HashMap}
sealed abstract class TransactionalStateConfig
abstract class PersistentStorageConfig extends TransactionalStateConfig
case class CassandraStorageConfig extends PersistentStorageConfig
case class TerracottaStorageConfig extends PersistentStorageConfig
case class TokyoCabinetStorageConfig extends PersistentStorageConfig
case class MongoStorageConfig extends PersistentStorageConfig
/**
* Scala API.
* <p/>
* Example Scala usage:
* <pre>
* val myMap = TransactionalState.newPersistentMap(CassandraStorageConfig)
* </pre>
*/
object TransactionalState extends TransactionalState
/**
* Java API.
* <p/>
* Example Java usage:
* <pre>
* TransactionalState state = new TransactionalState();
* TransactionalMap myMap = state.newPersistentMap(new CassandraStorageConfig());
* </pre>
*/
class TransactionalState {
def newPersistentMap(config: PersistentStorageConfig): TransactionalMap[AnyRef, AnyRef] = config match {
case CassandraStorageConfig() => new CassandraPersistentTransactionalMap
case MongoStorageConfig() => new MongoPersistentTransactionalMap
case TerracottaStorageConfig() => throw new UnsupportedOperationException
case TokyoCabinetStorageConfig() => throw new UnsupportedOperationException
}
def newPersistentVector(config: PersistentStorageConfig): TransactionalVector[AnyRef] = config match {
case CassandraStorageConfig() => new CassandraPersistentTransactionalVector
case MongoStorageConfig() => new MongoPersistentTransactionalVector
case TerracottaStorageConfig() => throw new UnsupportedOperationException
case TokyoCabinetStorageConfig() => throw new UnsupportedOperationException
}
def newPersistentRef(config: PersistentStorageConfig): TransactionalRef[AnyRef] = config match {
case CassandraStorageConfig() => new CassandraPersistentTransactionalRef
case MongoStorageConfig() => new MongoPersistentTransactionalRef
case TerracottaStorageConfig() => throw new UnsupportedOperationException
case TokyoCabinetStorageConfig() => throw new UnsupportedOperationException
}
def newInMemoryMap[K, V]: TransactionalMap[K, V] = new InMemoryTransactionalMap[K, V]
def newInMemoryVector[T]: TransactionalVector[T] = new InMemoryTransactionalVector[T]
def newInMemoryRef[T]: TransactionalRef[T] = new TransactionalRef[T]
}
/**
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
@serializable
trait Transactional {
// FIXME: won't work across the cluster
val uuid = Uuid.newUuid.toString
private[kernel] def begin
private[kernel] def commit
private[kernel] def rollback
protected def verifyTransaction = {
val cflowTx = TransactionManagement.threadBoundTx.get
if (!cflowTx.isDefined) {
throw new IllegalStateException("Can't access transactional reference outside the scope of a transaction [" + this + "]")
} else {
cflowTx.get.register(this)
}
}
}
/**
* Base trait for all state implementations (persistent or in-memory).
*
* FIXME: Create Java versions using pcollections
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
trait TransactionalMap[K, V] extends Transactional with scala.collection.mutable.Map[K, V] {
override def hashCode: Int = System.identityHashCode(this);
override def equals(other: Any): Boolean = false
def remove(key: K)
}
/**
* 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>
*/
class InMemoryTransactionalMap[K, V] extends TransactionalMap[K, V] {
protected[kernel] var state = new HashTrie[K, V]
protected[kernel] var snapshot = state
// ---- For Transactional ----
override def begin = snapshot = state
override def commit = snapshot = state
override def rollback = state = snapshot
// ---- Overriding scala.collection.mutable.Map behavior ----
override def contains(key: K): Boolean = {
verifyTransaction
state.contains(key)
}
override def clear = {
verifyTransaction
state = new HashTrie[K, V]
}
override def size: Int = {
verifyTransaction
state.size
}
// ---- For scala.collection.mutable.Map ----
override def remove(key: K) = {
verifyTransaction
state = state - key
}
override def elements: Iterator[(K, V)] = {
// verifyTransaction
state.elements
}
override def get(key: K): Option[V] = {
verifyTransaction
state.get(key)
}
override def put(key: K, value: V): Option[V] = {
verifyTransaction
val oldValue = state.get(key)
state = state.update(key, value)
oldValue
}
override def -=(key: K) = {
verifyTransaction
remove(key)
}
override def update(key: K, value: V) = {
verifyTransaction
put(key, value)
}
}
/**
* Base class for all persistent transactional map 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 PersistentTransactionalMap[K, V] extends TransactionalMap[K, V] {
// FIXME: need to handle remove in another changeSet
protected[kernel] val changeSet = new HashMap[K, V]
def getRange(start: Option[AnyRef], count: Int)
// ---- For Transactional ----
override def begin = {}
override def rollback = changeSet.clear
// ---- For scala.collection.mutable.Map ----
override def put(key: K, value: V): Option[V] = {
verifyTransaction
changeSet += key -> value
None // always return None to speed up writes (else need to go to DB to get
}
override def -=(key: K) = remove(key)
override def update(key: K, value: V) = put(key, value)
}
/**
* Implementation of <tt>PersistentTransactionalMap</tt> for every concrete
* storage will have the same workflow. This abstracts the workflow.
*
* Subclasses just need to provide the actual concrete instance for the
* abstract val <tt>storage</tt>.
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
abstract class TemplatePersistentTransactionalMap extends PersistentTransactionalMap[AnyRef, AnyRef] {
// to be concretized in subclasses
val storage: MapStorage
override def remove(key: AnyRef) = {
verifyTransaction
if (changeSet.contains(key)) changeSet -= key
else storage.removeMapStorageFor(uuid, key)
}
override def getRange(start: Option[AnyRef], count: Int) =
getRange(start, None, count)
def getRange(start: Option[AnyRef], finish: Option[AnyRef], count: Int) = {
verifyTransaction
try {
storage.getMapStorageRangeFor(uuid, start, finish, count)
} catch {
case e: Exception => Nil
}
}
// ---- For Transactional ----
override def commit = {
storage.insertMapStorageEntriesFor(uuid, changeSet.toList)
changeSet.clear
}
// ---- Overriding scala.collection.mutable.Map behavior ----
override def clear = {
verifyTransaction
try {
storage.removeMapStorageFor(uuid)
} catch {
case e: Exception => {}
}
}
override def contains(key: AnyRef): Boolean = {
try {
verifyTransaction
storage.getMapStorageEntryFor(uuid, key).isDefined
} catch {
case e: Exception => false
}
}
override def size: Int = {
verifyTransaction
try {
storage.getMapStorageSizeFor(uuid)
} catch {
case e: Exception => 0
}
}
// ---- For scala.collection.mutable.Map ----
override def get(key: AnyRef): Option[AnyRef] = {
verifyTransaction
// if (changeSet.contains(key)) changeSet.get(key)
// else {
val result = try {
storage.getMapStorageEntryFor(uuid, key)
} catch {
case e: Exception => None
}
result
//}
}
override def elements: Iterator[Tuple2[AnyRef, AnyRef]] = {
//verifyTransaction
new Iterator[Tuple2[AnyRef, AnyRef]] {
private val originalList: List[Tuple2[AnyRef, AnyRef]] = try {
storage.getMapStorageFor(uuid)
} catch {
case e: Throwable => Nil
}
private var elements = originalList.reverse
override def next: Tuple2[AnyRef, AnyRef]= synchronized {
val element = elements.head
elements = elements.tail
element
}
override def hasNext: Boolean = synchronized { !elements.isEmpty }
}
}
}
/**
* Implements a persistent transactional map based on the Cassandra distributed P2P key-value storage.
*
* @author <a href="http://debasishg.blogspot.com">Debasish Ghosh</a>
*/
class CassandraPersistentTransactionalMap extends TemplatePersistentTransactionalMap {
val storage = CassandraStorage
}
/**
* Implements a persistent transactional map based on the MongoDB distributed P2P key-value storage.
*
* @author <a href="http://debasishg.blogspot.com">Debasish Ghosh</a>
*/
class MongoPersistentTransactionalMap extends TemplatePersistentTransactionalMap {
val storage = MongoStorage
}
/**
* Base for all transactional vector implementations.
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
abstract class TransactionalVector[T] extends Transactional with RandomAccessSeq[T] {
override def hashCode: Int = System.identityHashCode(this);
override def equals(other: Any): Boolean = false
def add(elem: T)
def get(index: Int): T
def getRange(start: Int, count: Int): List[T]
}
/**
* Implements an in-memory transactional vector.
*
* 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>
*/
class InMemoryTransactionalVector[T] extends TransactionalVector[T] {
private[kernel] var state: Vector[T] = EmptyVector
private[kernel] var snapshot = state
def add(elem: T) = {
verifyTransaction
state = state + elem
}
def get(index: Int): T = {
verifyTransaction
state(index)
}
def getRange(start: Int, count: Int): List[T] = {
verifyTransaction
state.slice(start, count).toList.asInstanceOf[List[T]]
}
// ---- For Transactional ----
override def begin = snapshot = state
override def commit = snapshot = state
override def rollback = state = snapshot
// ---- For Seq ----
def length: Int = {
verifyTransaction
state.length
}
def apply(index: Int): T = {
verifyTransaction
state(index)
}
override def elements: Iterator[T] = {
//verifyTransaction
state.elements
}
override def toList: List[T] = {
verifyTransaction
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] val changeSet = new ArrayBuffer[T]
// ---- For Transactional ----
override def begin = {}
override def rollback = changeSet.clear
// ---- For TransactionalVector ----
override def add(value: T) = {
verifyTransaction
changeSet += value
}
}
/**
* Implements a template for a concrete persistent transactional vector based storage.
*
* @author <a href="http://debasishg.blogspot.com">Debasish Ghosh</a>
*/
abstract class TemplatePersistentTransactionalVector extends PersistentTransactionalVector[AnyRef] {
val storage: VectorStorage
// ---- For TransactionalVector ----
override def get(index: Int): AnyRef = {
verifyTransaction
if (changeSet.size > index) changeSet(index)
else storage.getVectorStorageEntryFor(uuid, index)
}
override def getRange(start: Int, count: Int): List[AnyRef] =
getRange(Some(start), None, count)
def getRange(start: Option[Int], finish: Option[Int], count: Int): List[AnyRef] = {
verifyTransaction
storage.getVectorStorageRangeFor(uuid, start, finish, count)
}
override def length: Int = {
verifyTransaction
storage.getVectorStorageSizeFor(uuid)
}
override def apply(index: Int): AnyRef = get(index)
override def first: AnyRef = get(0)
override def last: AnyRef = {
verifyTransaction
val l = length
if (l == 0) throw new NoSuchElementException("Vector is empty")
get(length - 1)
}
// ---- For Transactional ----
override def commit = {
// FIXME: should use batch function once the bug is resolved
for (element <- changeSet) storage.insertVectorStorageEntryFor(uuid, element)
changeSet.clear
}
}
/**
* Implements a persistent transactional vector based on the Cassandra distributed P2P key-value storage.
*
* @author <a href="http://debasishg.blogspot.com">Debaissh Ghosh</a>
*/
class CassandraPersistentTransactionalVector extends TemplatePersistentTransactionalVector {
val storage = CassandraStorage
}
/**
* Implements a persistent transactional vector based on the MongoDB distributed P2P key-value storage.
*
* @author <a href="http://debasishg.blogspot.com">Debaissh Ghosh</a>
*/
class MongoPersistentTransactionalVector extends TemplatePersistentTransactionalVector {
val storage = MongoStorage
}
/**
* Implements a transactional reference.
*
* 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>
*/
class TransactionalRef[T] extends Transactional {
private[kernel] var ref: Option[T] = None
private[kernel] var snapshot: Option[T] = None
override def begin = if (ref.isDefined) snapshot = Some(ref.get)
override def commit = if (ref.isDefined) snapshot = Some(ref.get)
override def rollback = if (snapshot.isDefined) ref = Some(snapshot.get)
def swap(elem: T) = {
verifyTransaction
ref = Some(elem)
}
def get: Option[T] = {
verifyTransaction
ref
}
def getOrElse(default: => T): T = {
verifyTransaction
ref.getOrElse(default)
}
def isDefined: Boolean = {
verifyTransaction
ref.isDefined
}
}
abstract class TemplatePersistentTransactionalRef extends TransactionalRef[AnyRef] {
val storage: RefStorage
override def commit = if (ref.isDefined) {
storage.insertRefStorageFor(uuid, ref.get)
ref = None
}
override def rollback = ref = None
override def get: Option[AnyRef] = {
verifyTransaction
storage.getRefStorageFor(uuid)
}
override def isDefined: Boolean = get.isDefined
override def getOrElse(default: => AnyRef): AnyRef = {
val ref = get
if (ref.isDefined) ref
else default
}
}
class CassandraPersistentTransactionalRef extends TemplatePersistentTransactionalRef {
val storage = CassandraStorage
}
class MongoPersistentTransactionalRef extends TemplatePersistentTransactionalRef {
val storage = MongoStorage
}

View file

@ -0,0 +1,143 @@
/**
* Copyright (C) 2009 Scalable Solutions.
*/
package se.scalablesolutions.akka.kernel.state
import kernel.stm.{Ref, TransactionManagement}
import akka.collection._
import org.codehaus.aspectwerkz.proxy.Uuid
import scala.collection.mutable.{ArrayBuffer, HashMap}
sealed abstract class TransactionalStateConfig
abstract class PersistentStorageConfig extends TransactionalStateConfig
case class CassandraStorageConfig extends PersistentStorageConfig
case class TerracottaStorageConfig extends PersistentStorageConfig
case class TokyoCabinetStorageConfig extends PersistentStorageConfig
case class MongoStorageConfig extends PersistentStorageConfig
/**
* Scala API.
* <p/>
* Example Scala usage:
* <pre>
* val myMap = TransactionalState.newPersistentMap(CassandraStorageConfig)
* </pre>
*/
object TransactionalState extends TransactionalState
/**
* Java API.
* <p/>
* Example Java usage:
* <pre>
* TransactionalState state = new TransactionalState();
* TransactionalMap myMap = state.newPersistentMap(new CassandraStorageConfig());
* </pre>
*/
class TransactionalState {
def newPersistentMap(config: PersistentStorageConfig): TransactionalMap[AnyRef, AnyRef] = config match {
case CassandraStorageConfig() => new CassandraPersistentTransactionalMap
case MongoStorageConfig() => new MongoPersistentTransactionalMap
case TerracottaStorageConfig() => throw new UnsupportedOperationException
case TokyoCabinetStorageConfig() => throw new UnsupportedOperationException
}
def newPersistentVector(config: PersistentStorageConfig): TransactionalVector[AnyRef] = config match {
case CassandraStorageConfig() => new CassandraPersistentTransactionalVector
case MongoStorageConfig() => new MongoPersistentTransactionalVector
case TerracottaStorageConfig() => throw new UnsupportedOperationException
case TokyoCabinetStorageConfig() => throw new UnsupportedOperationException
}
def newPersistentRef(config: PersistentStorageConfig): TransactionalRef[AnyRef] = config match {
case CassandraStorageConfig() => new CassandraPersistentTransactionalRef
case MongoStorageConfig() => throw new UnsupportedOperationException
case TerracottaStorageConfig() => throw new UnsupportedOperationException
case TokyoCabinetStorageConfig() => throw new UnsupportedOperationException
}
def newMap[K, V]: TransactionalMap[K, V] = new InMemoryTransactionalMap[K, V]
def newVector[T]: TransactionalVector[T] = new InMemoryTransactionalVector[T]
def newRef[T]: TransactionalRef[T] = new TransactionalRef[T]
def newRef[T](init: T): TransactionalRef[T] = new TransactionalRef[T](init)
}
/**
* Implements a transactional reference. Based on the Multiverse STM.
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
class TransactionalRef[T](elem: T) extends Transactional {
def this() = this(null.asInstanceOf[T])
private[kernel] val ref = new Ref[T](elem)
def swap(elem: T) = ref.set(elem)
def get: Option[T] = {
if (ref.isNull) None
else Some(ref.get)
}
def getOrWait: T = ref.getOrAwait
def getOrElse(default: => T): T = {
if (ref.isNull) default
else ref.get
}
def isDefined: Boolean = !ref.isNull
}
/**
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
@serializable
trait Transactional {
// FIXME: won't work across the cluster
val uuid = Uuid.newUuid.toString
private[kernel] def commit = {}
protected def verifyTransaction = {
val cflowTx = TransactionManagement.threadBoundTx.get
if (!cflowTx.isDefined) throw new IllegalStateException("Can't access transactional reference outside the scope of a transaction [" + this + "]")
else cflowTx.get.register(this)
}
}
/**
* Base trait for all state implementations (persistent or in-memory).
*
* FIXME: Create Java versions using pcollections
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
trait TransactionalMap[K, V] extends Transactional with scala.collection.mutable.Map[K, V] {
override def hashCode: Int = System.identityHashCode(this)
override def equals(other: Any): Boolean = false
def remove(key: K)
}
/**
* Base for all transactional vector implementations.
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
abstract class TransactionalVector[T] extends Transactional with RandomAccessSeq[T] {
override def hashCode: Int = System.identityHashCode(this)
override def equals(other: Any): Boolean = false
def add(elem: T)
def get(index: Int): T
def getRange(start: Int, count: Int): List[T]
}

177
kernel/src/main/scala/stm/Transaction.scala Normal file → Executable file
View file

@ -4,9 +4,180 @@
package se.scalablesolutions.akka.kernel.stm
import java.util.concurrent.atomic.{AtomicInteger, AtomicLong}
import kernel.state.Transactional
import kernel.util.Logging
import org.multiverse.api.{Transaction => MultiverseTransaction}
import org.multiverse.stms.alpha.AlphaStm
import org.multiverse.utils.GlobalStmInstance
import org.multiverse.utils.TransactionThreadLocal._
import java.util.concurrent.atomic.AtomicInteger
/**
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
object Multiverse {
val STM = new AlphaStm
GlobalStmInstance.set(STM)
setThreadLocalTransaction(null)
}
/**
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
@serializable class Transaction extends Logging {
private[this] var _id = 0L
def id = _id
@volatile private[this] var status: TransactionStatus = TransactionStatus.New
private[kernel] var transaction: MultiverseTransaction = _
private[this] val transactionalItems = new ChangeSet
private[this] var participants: List[String] = Nil
private[this] var precommitted: List[String] = Nil
private[this] val depth = new AtomicInteger(0)
def increment = synchronized { depth.incrementAndGet }
def decrement = synchronized { depth.decrementAndGet }
def isTopLevel = synchronized { depth.get == 0 }
def register(transactional: Transactional) = synchronized {
ensureIsActiveOrNew
transactionalItems + transactional
}
def begin(participant: String) = synchronized {
ensureIsActiveOrNew
transaction = Multiverse.STM.startUpdateTransaction
_id = transaction.getReadVersion
log.debug("Creating a new transaction with id [%s]", _id)
if (status == TransactionStatus.New) log.debug("TX BEGIN - Server with UUID [%s] is starting NEW transaction [%s]", participant, toString)
else log.debug("Server [%s] is participating in transaction", participant)
participants ::= participant
status = TransactionStatus.Active
}
def precommit(participant: String) = synchronized {
if (status == TransactionStatus.Active) {
log.debug("TX PRECOMMIT - Pre-committing transaction [%s] for server with UUID [%s]", toString, participant)
precommitted ::= participant
}
}
def commit(participant: String): Boolean = synchronized {
if (status == TransactionStatus.Active) {
log.debug("TX COMMIT - Committing transaction [%s] for server with UUID [%s]", toString, participant)
val haveAllPreCommitted =
if (participants.size == precommitted.size) {{
for (part <- participants) yield {
if (precommitted.exists(_ == part)) true
else false
}}.exists(_ == true)
} else false
if (haveAllPreCommitted && transaction != null) {
transaction.commit
transactionalItems.items.foreach(_.commit)
status = TransactionStatus.Completed
reset
true
} else false
} else {
reset
true
}
}
def rollback(participant: String) = synchronized {
ensureIsActiveOrAborted
log.debug("TX ROLLBACK - Server with UUID [%s] has initiated transaction rollback for [%s]", participant, toString)
transaction.abort
status = TransactionStatus.Aborted
reset
}
def rollbackForRescheduling(participant: String) = synchronized {
ensureIsActiveOrAborted
log.debug("TX ROLLBACK for recheduling - Server with UUID [%s] has initiated transaction rollback for [%s]", participant, toString)
transaction.abort
reset
}
def join(participant: String) = synchronized {
ensureIsActive
log.debug("TX JOIN - Server with UUID [%s] is joining transaction [%s]" , participant, toString)
participants ::= participant
}
def isNew = status == TransactionStatus.New
def isActive = status == TransactionStatus.Active
def isCompleted = status == TransactionStatus.Completed
def isAborted = status == TransactionStatus.Aborted
private def reset = {
transactionalItems.clear
participants = Nil
precommitted = Nil
}
private def ensureIsActive = if (status != TransactionStatus.Active)
throw new IllegalStateException("Expected ACTIVE transaction - current status [" + status + "]: " + toString)
private def ensureIsActiveOrAborted = if (!(status == TransactionStatus.Active || status == TransactionStatus.Aborted))
throw new IllegalStateException("Expected ACTIVE or ABORTED transaction - current status [" + status + "]: " + toString)
private def ensureIsActiveOrNew = if (!(status == TransactionStatus.Active || status == TransactionStatus.New))
throw new IllegalStateException("Expected ACTIVE or NEW transaction - current status [" + status + "]: " + toString)
// For reinitialize transaction after sending it over the wire
private[kernel] def reinit = synchronized {
import net.lag.logging.{Logger, Level}
if (log == null) {
log = Logger.get(this.getClass.getName)
log.setLevel(Level.ALL)
}
}
override def equals(that: Any): Boolean = synchronized {
that != null &&
that.isInstanceOf[Transaction] &&
that.asInstanceOf[Transaction].id == this.id
}
override def hashCode(): Int = id.toInt
override def toString(): String = synchronized {
"Transaction[" + id + ", " + status + "]"
}
}
@serializable sealed abstract class TransactionStatus
object TransactionStatus {
@ -20,18 +191,17 @@ object TransactionStatus {
* Represents a snapshot of the current invocation.
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
object TransactionIdFactory {
// FIXME: will not work in distributed env
private val currentId = new AtomicLong(0L)
def newId = currentId.getAndIncrement
}
*/
/**
* Represents a snapshot of the current invocation.
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
@serializable class Transaction extends Logging {
val id = TransactionIdFactory.newId
@ -154,3 +324,4 @@ object TransactionIdFactory {
"Transaction[" + id + ", " + status + "]"
}
}
*/

4
kernel/src/main/scala/stm/TransactionManagement.scala Normal file → Executable file
View file

@ -10,6 +10,8 @@ import kernel.reactor.MessageInvocation
import kernel.util.Logging
import org.codehaus.aspectwerkz.proxy.Uuid // FIXME is java.util.UUID better?
import org.multiverse.utils.TransactionThreadLocal._
class TransactionRollbackException(msg: String) extends RuntimeException(msg)
class TransactionAwareWrapperException(val cause: Throwable, val tx: Option[Transaction]) extends RuntimeException(cause) {
@ -46,6 +48,7 @@ trait TransactionManagement extends Logging {
val tx = Some(newTx)
activeTx = tx
threadBoundTx.set(tx)
setThreadLocalTransaction(tx.get.transaction)
tx
}
@ -110,6 +113,7 @@ trait TransactionManagement extends Logging {
protected def removeTransactionIfTopLevel = if (isTransactionTopLevel) {
activeTx = None
threadBoundTx.set(None)
setThreadLocalTransaction(null)
}
protected def reenteringExistingTransaction= if (activeTx.isDefined) {

View file

@ -26,9 +26,9 @@ case class FailureOneWay(key: String, value: String, failer: Actor)
class InMemStatefulActor extends Actor {
timeout = 100000
makeTransactionRequired
private val mapState = TransactionalState.newInMemoryMap[String, String]
private val vectorState = TransactionalState.newInMemoryVector[String]
private val refState = TransactionalState.newInMemoryRef[String]
private val mapState = TransactionalState.newMap[String, String]
private val vectorState = TransactionalState.newVector[String]
private val refState = TransactionalState.newRef[String]("")
def receive: PartialFunction[Any, Unit] = {
case GetMapState(key) =>
@ -217,14 +217,26 @@ class InMemoryActorSpec extends TestCase {
def testRefShouldRollbackStateForStatefulServerInCaseOfFailure = {
val stateful = new InMemStatefulActor
stateful.start
println("------------ 1")
try {
stateful !! SetRefState("init") // set init state
} catch {
case e: RuntimeException =>
println("------------ 1.1")
stateful !! SetRefState("init") // set init state
println("------------ 1.2")
}
println("------------ 2")
val failer = new InMemFailerActor
failer.start
try {
println("------------ 3")
stateful !! Failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method
println("------------ 4")
fail("should have thrown an exception")
} catch {case e: RuntimeException => {}}
} catch {case e: RuntimeException => {
println("------------ 5")
}}
assertEquals("init", (stateful !! GetRefState).get) // check that state is == init state
}
}
}

View file

@ -24,7 +24,7 @@ class TxActor(clasher: Actor) extends Actor {
}
class TxClasherActor extends Actor {
val vector = TransactionalState.newInMemoryVector[String]
val vector = TransactionalState.newVector[String]
timeout = 1000000
makeTransactionRequired
var count = 0
@ -59,7 +59,7 @@ class TxActorOneWay(clasher: Actor) extends Actor {
}
class TxClasherActorOneWay extends Actor {
val vector = TransactionalState.newInMemoryVector[String]
val vector = TransactionalState.newVector[String]
timeout = 1000000
makeTransactionRequired
var count = 0
@ -146,4 +146,4 @@ class TransactionClasherSpec extends TestCase {
assertEquals("First", (clasher !! "Index1").get)
}
*/
}
}

0
pom.xml Normal file → Executable file
View file

5
util-java/pom.xml Normal file → Executable file
View file

@ -25,6 +25,11 @@
<artifactId>protobuf-java</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.multiverse</groupId>
<artifactId>multiverse</artifactId>
<version>0.3</version>
</dependency>
</dependencies>
<build>

View file

@ -0,0 +1,248 @@
package se.scalablesolutions.akka.kernel.stm;
import static org.multiverse.api.StmUtils.retry;
import org.multiverse.api.Transaction;
import org.multiverse.api.exceptions.LoadUncommittedAtomicObjectException;
import org.multiverse.api.exceptions.ReadonlyException;
import org.multiverse.datastructures.refs.ManagedRef;
import org.multiverse.stms.alpha.*;
import org.multiverse.stms.alpha.mixins.FastAtomicObjectMixin;
import org.multiverse.templates.AtomicTemplate;
import org.multiverse.datastructures.refs.manual.*;
/**
* A manual instrumented {@link org.multiverse.datastructures.refs.ManagedRef} implementation.
* If this class is used, you don't need to worry about instrumentation/javaagents and
* stuff like this.
*
* It is added to get the Akka project up and running, but probably will removed when the instrumentation
* is 100% up and running and this can be done compiletime instead of messing with javaagents.
*
* @author Peter Veentjer
*/
public final class Ref<E> extends FastAtomicObjectMixin implements ManagedRef<E> {
public Ref() {
new AtomicTemplate() {
@Override
public Object execute(Transaction t) throws Exception {
((Transaction) t).attachNew(new RefTranlocal(Ref.this));
return null;
}
}.execute();
}
public Ref(Transaction t) {
((Transaction) t).attachNew(new RefTranlocal(Ref.this));
}
public Ref(final E value) {
new AtomicTemplate() {
@Override
public Object execute(Transaction t) throws Exception {
((Transaction) t).attachNew(new RefTranlocal(Ref.this, value));
return null;
}
}.execute();
}
public Ref(Transaction t, final E value) {
((Transaction) t).attachNew(new RefTranlocal(Ref.this, value));
}
public E get() {
return new AtomicTemplate<E>() {
@Override
public E execute(Transaction t) throws Exception {
RefTranlocal<E> tranlocalRef = (RefTranlocal) ((Transaction) t).privatize(Ref.this);
return tranlocalRef.get();
}
}.execute();
}
public E get(Transaction t) {
RefTranlocal<E> tranlocalRef = (RefTranlocal) ((Transaction) t).privatize(Ref.this);
return tranlocalRef.get();
}
@Override
public E getOrAwait() {
return new AtomicTemplate<E>() {
@Override
public E execute(Transaction t) throws Exception {
RefTranlocal<E> tranlocalRef = (RefTranlocal) ((Transaction) t).privatize(Ref.this);
return tranlocalRef.getOrAwait();
}
}.execute();
}
public E getOrAwait(Transaction t) {
RefTranlocal<E> tranlocalRef = (RefTranlocal) ((Transaction) t).privatize(Ref.this);
return tranlocalRef.getOrAwait();
}
@Override
public E set(final E newRef) {
return new AtomicTemplate<E>() {
@Override
public E execute(Transaction t) throws Exception {
RefTranlocal<E> tranlocalRef = (RefTranlocal) ((Transaction) t).privatize(Ref.this);
return tranlocalRef.set(newRef);
}
}.execute();
}
public E set(Transaction t, final E newRef) {
RefTranlocal<E> tranlocalRef = (RefTranlocal) ((Transaction) t).privatize(Ref.this);
return tranlocalRef.set(newRef);
}
@Override
public boolean isNull() {
return new AtomicTemplate<Boolean>() {
@Override
public Boolean execute(Transaction t) throws Exception {
RefTranlocal<E> tranlocalRef = (RefTranlocal) ((Transaction) t).privatize(Ref.this);
return tranlocalRef.isNull();
}
}.execute();
}
public boolean isNull(Transaction t) {
RefTranlocal<E> tranlocalRef = (RefTranlocal) ((Transaction) t).privatize(Ref.this);
return tranlocalRef.isNull();
}
@Override
public E clear() {
return new AtomicTemplate<E>() {
@Override
public E execute(Transaction t) throws Exception {
RefTranlocal<E> tranlocalRef = (RefTranlocal) ((Transaction) t).privatize(Ref.this);
return tranlocalRef.clear();
}
}.execute();
}
public E clear(Transaction t) {
RefTranlocal<E> tranlocalRef = (RefTranlocal) ((Transaction) t).privatize(Ref.this);
return tranlocalRef.clear();
}
@Override
public RefTranlocal<E> privatize(long readVersion) {
RefTranlocal<E> origin = (RefTranlocal<E>) load(readVersion);
if (origin == null) {
throw new LoadUncommittedAtomicObjectException();
}
return new RefTranlocal<E>(origin);
}
}
class RefTranlocal<E> extends Tranlocal {
//field belonging to the stm.
Ref atomicObject;
RefTranlocal origin;
E ref;
RefTranlocal(RefTranlocal<E> origin) {
this.version = origin.version;
this.atomicObject = origin.atomicObject;
this.ref = origin.ref;
this.origin = origin;
}
RefTranlocal(Ref<E> owner) {
this(owner, null);
}
RefTranlocal(Ref<E> owner, E ref) {
this.version = Long.MIN_VALUE;
this.atomicObject = owner;
this.ref = ref;
}
@Override
public AlphaAtomicObject getAtomicObject() {
return atomicObject;
}
public E clear() {
E oldValue = ref;
ref = null;
return oldValue;
}
public boolean isNull() {
return ref == null;
}
public E get() {
return ref;
}
public E set(E newValue) {
if (committed) {
throw new ReadonlyException();
}
E oldValue = ref;
this.ref = newValue;
return oldValue;
}
public E getOrAwait() {
if (isNull()) {
retry();
}
return ref;
}
@Override
public void prepareForCommit(long writeVersion) {
this.version = writeVersion;
this.committed = true;
this.origin = null;
}
@Override
public TranlocalSnapshot takeSnapshot() {
return new RefTranlocalSnapshot<E>(this);
}
@Override
public DirtinessStatus getDirtinessStatus() {
if (committed) {
return DirtinessStatus.committed;
} else if (origin == null) {
return DirtinessStatus.fresh;
} else if (origin.ref != this.ref) {
return DirtinessStatus.dirty;
} else {
return DirtinessStatus.clean;
}
}
}
class RefTranlocalSnapshot<E> extends TranlocalSnapshot {
final RefTranlocal tranlocal;
final E value;
RefTranlocalSnapshot(RefTranlocal<E> tranlocal) {
this.tranlocal = tranlocal;
this.value = tranlocal.ref;
}
@Override
public Tranlocal getTranlocal() {
return tranlocal;
}
@Override
public void restore() {
tranlocal.ref = value;
}
}