actors example - stock server
This commit is contained in:
@@ -1,186 +0,0 @@
|
||||
package actors
|
||||
|
||||
import std.concurrent.*
|
||||
import std.util.*
|
||||
|
||||
import java.util.concurrent.*
|
||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
import java.util.Date
|
||||
|
||||
/*
|
||||
Message handling class which process only one message at any given moment
|
||||
|
||||
Three main ways to use it
|
||||
- post and forget
|
||||
- post and await result
|
||||
- post and assign callback to be called when message processed
|
||||
*/
|
||||
abstract class Actor(protected val executor: Executor) {
|
||||
// we can not do it private or protected
|
||||
// otherwise updater defined in class object will not be able to access it
|
||||
volatile var queue : FunctionalQueue<Any> = emptyQueue
|
||||
|
||||
/*
|
||||
Handle message and return result
|
||||
This method guaranteed to be executed only one per object at any given time
|
||||
*/
|
||||
protected abstract fun onMessage(message: Any) : Any?
|
||||
|
||||
/*
|
||||
Post message to the actor.
|
||||
The method returns immediately and the message itself will be processed later
|
||||
*/
|
||||
fun post(message: Any) {
|
||||
while(true) {
|
||||
val q = queue
|
||||
if(q.empty) {
|
||||
if(queueUpdater.compareAndSet(this, q, busyEmptyQueue)) {
|
||||
executor.execute { process(message) }
|
||||
break
|
||||
}
|
||||
}
|
||||
else {
|
||||
val newQueue = (if(q == busyEmptyQueue) emptyQueue else q) add message
|
||||
if(queueUpdater.compareAndSet(this, q, newQueue)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Post message to the actor and schedule callback to be executed on given executor when message processed
|
||||
*/
|
||||
fun post(message: Any, executor: Executor = this.executor, callback: (Any?)->Unit) =
|
||||
post(Callback(message, executor, callback))
|
||||
|
||||
/*
|
||||
Send message to the actor and await result
|
||||
*/
|
||||
fun send(message: Any) : Any? {
|
||||
val request = Request(message)
|
||||
post(request)
|
||||
request.await()
|
||||
return request.result
|
||||
}
|
||||
|
||||
private fun nextMessage() {
|
||||
while(true) {
|
||||
val q = queue
|
||||
if(q == busyEmptyQueue) {
|
||||
if(queueUpdater.compareAndSet(this, busyEmptyQueue, emptyQueue)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
val removed = q.removeFirst()
|
||||
val newQueue = if(removed._2.empty) busyEmptyQueue else removed._2
|
||||
if(queueUpdater.compareAndSet(this, q, newQueue)) {
|
||||
executor.execute { process(removed._1) }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun process(message: Any) {
|
||||
when(message) {
|
||||
is Request -> {
|
||||
message.result = onMessage(message.message)
|
||||
message.countDown()
|
||||
}
|
||||
is Callback -> {
|
||||
val result = onMessage(message.message)
|
||||
message.executor execute {
|
||||
val callback = message.callback;
|
||||
callback(result)
|
||||
}
|
||||
}
|
||||
else -> onMessage(message)
|
||||
}
|
||||
|
||||
nextMessage()
|
||||
}
|
||||
|
||||
/*
|
||||
Create actor on the same executor
|
||||
*/
|
||||
fun actor(handler: (Any)->Any?) = executor.actor(handler)
|
||||
|
||||
class object {
|
||||
val queueUpdater = AtomicReferenceFieldUpdater.newUpdater(typeinfo<Actor>.javaClassForType,typeinfo<FunctionalQueue<Any>>().javaClassForType, "queue").sure()
|
||||
val emptyQueue = FunctionalQueue<Any>()
|
||||
val busyEmptyQueue = FunctionalQueue<Any>() add "busy empty queue"
|
||||
|
||||
class Request(val message: Any) : java.util.concurrent.CountDownLatch(1) {
|
||||
var result: Any? = null
|
||||
}
|
||||
|
||||
class Callback(val message: Any, val executor: Executor, val callback: (Any?) -> Unit)
|
||||
}
|
||||
}
|
||||
|
||||
fun Executor.actor(handler: (Any)->Any?) : Actor = object: Actor(this) {
|
||||
override fun onMessage(message: Any) {
|
||||
handler(message)
|
||||
}
|
||||
}
|
||||
|
||||
fun singleThreadActor(handler: (Any)->Any?) : Actor = Executors.newSingleThreadExecutor().sure().actor(handler)
|
||||
|
||||
class App() : Actor(Executors.newFixedThreadPool(10).sure()) {
|
||||
private val logger = executor.actor { message ->
|
||||
println("${Date()}:\t\t$message")
|
||||
}
|
||||
|
||||
private val actors = Array<Actor>(100, { createChild(it) });
|
||||
|
||||
private var finishedChildren = actors.size
|
||||
|
||||
override fun onMessage(message: Any) {
|
||||
when(message) {
|
||||
"start" -> {
|
||||
logger post "app started"
|
||||
for(a in actors) {
|
||||
a post "start"
|
||||
}
|
||||
}
|
||||
"child finished" -> {
|
||||
if(--finishedChildren == 0) {
|
||||
logger send "app finished"
|
||||
(executor as ExecutorService).shutdown()
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
logger post "unknown message $message"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createChild(index: Int) : Actor = actor { message ->
|
||||
val next = (index + 1) % actors.size
|
||||
when(message) {
|
||||
"start" -> {
|
||||
logger post "$index started"
|
||||
actors[next] post #(index, 0)
|
||||
}
|
||||
is Tuple2<Int,Int> -> {
|
||||
logger post "$index received $message"
|
||||
val from = message._1
|
||||
val value = message._2
|
||||
if(next != from) {
|
||||
actors[next] post #(from, value+1)
|
||||
}
|
||||
else {
|
||||
logger post "$index finished"
|
||||
this@App post "child finished"
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
App() post "start"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="KotlinRuntime" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AntConfiguration">
|
||||
<defaultAnt bundledAnt="true" />
|
||||
</component>
|
||||
<component name="CompilerConfiguration">
|
||||
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="?*.properties" />
|
||||
<entry name="?*.xml" />
|
||||
<entry name="?*.gif" />
|
||||
<entry name="?*.png" />
|
||||
<entry name="?*.jpeg" />
|
||||
<entry name="?*.jpg" />
|
||||
<entry name="?*.html" />
|
||||
<entry name="?*.dtd" />
|
||||
<entry name="?*.tld" />
|
||||
<entry name="?*.ftl" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing enabled="false" useClasspath="true" />
|
||||
</component>
|
||||
<component name="CopyrightManager" default="">
|
||||
<module2copyright />
|
||||
</component>
|
||||
<component name="DependencyValidationManager">
|
||||
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
||||
</component>
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/actors.iml" filepath="$PROJECT_DIR$/actors.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="" />
|
||||
</component>
|
||||
<component name="libraryTable">
|
||||
<library name="KotlinRuntime">
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/../../../dist/kotlinc/lib" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
<jarDirectory url="file://$PROJECT_DIR$/../../../dist/kotlinc/lib" recursive="false" />
|
||||
</library>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,523 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="9624598b-68cd-4d51-9271-5ac61ef5a43a" name="Default" comment="" />
|
||||
<ignored path="actors.iws" />
|
||||
<ignored path=".idea/workspace.xml" />
|
||||
<option name="TRACKING_ENABLED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
|
||||
<component name="CreatePatchCommitExecutor">
|
||||
<option name="PATCH_PATH" value="" />
|
||||
</component>
|
||||
<component name="DaemonCodeAnalyzer">
|
||||
<disable_hints />
|
||||
</component>
|
||||
<component name="DebuggerManager">
|
||||
<breakpoint_any>
|
||||
<breakpoint>
|
||||
<option name="NOTIFY_CAUGHT" value="true" />
|
||||
<option name="NOTIFY_UNCAUGHT" value="true" />
|
||||
<option name="ENABLED" value="false" />
|
||||
<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>
|
||||
<option name="NOTIFY_CAUGHT" value="true" />
|
||||
<option name="NOTIFY_UNCAUGHT" value="true" />
|
||||
<option name="ENABLED" value="false" />
|
||||
<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_any>
|
||||
<breakpoint_rules />
|
||||
<ui_properties />
|
||||
</component>
|
||||
<component name="FavoritesManager">
|
||||
<favorites_list name="actors" />
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf>
|
||||
<file leaf-file-name="Main.kt" pinned="false" current="true" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/src/Main.kt">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="32" column="57" selection-start="881" selection-end="881" vertical-scroll-proportion="1.3675214">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
</leaf>
|
||||
</component>
|
||||
<component name="ProjectFrameBounds">
|
||||
<option name="y" value="22" />
|
||||
<option name="width" value="1440" />
|
||||
<option name="height" value="874" />
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectReloadState">
|
||||
<option name="STATE" value="0" />
|
||||
</component>
|
||||
<component name="ProjectView">
|
||||
<navigator currentView="ProjectPane" proportions="" version="1" splitterProportion="0.5">
|
||||
<flattenPackages />
|
||||
<showMembers />
|
||||
<showModules />
|
||||
<showLibraryContents />
|
||||
<hideEmptyPackages />
|
||||
<abbreviatePackageNames />
|
||||
<autoscrollToSource />
|
||||
<autoscrollFromSource />
|
||||
<sortByType />
|
||||
</navigator>
|
||||
<panes>
|
||||
<pane id="Scope">
|
||||
<subPane subId="Project Files">
|
||||
<PATH>
|
||||
<PATH_ELEMENT USER_OBJECT="Root">
|
||||
<option name="myItemId" value="" />
|
||||
<option name="myItemType" value="" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="actors" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="actors" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="actors" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="actors" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="actors" />
|
||||
<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>
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="PackagesPane">
|
||||
<subPane>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="actors" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="actors" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewModuleNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
</subPane>
|
||||
</pane>
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="project.structure.last.edited" value="Modules" />
|
||||
<property name="GoToFile.includeJavaFiles" value="false" />
|
||||
<property name="project.structure.proportion" value="0.15" />
|
||||
<property name="GoToClass.toSaveIncludeLibraries" value="false" />
|
||||
<property name="recentsLimit" value="5" />
|
||||
<property name="MemberChooser.sorted" value="false" />
|
||||
<property name="MemberChooser.showClasses" value="true" />
|
||||
<property name="project.structure.side.proportion" value="0.2" />
|
||||
<property name="GoToClass.includeLibraries" value="false" />
|
||||
<property name="dynamic.classpath" value="false" />
|
||||
<property name="MemberChooser.copyJavadoc" value="false" />
|
||||
</component>
|
||||
<component name="RunManager" selected="Kotlin.org.jetbrains.kotlin.examples.actors">
|
||||
<configuration default="false" name="org.jetbrains.kotlin.examples.actors" type="JetRunConfigurationType" factoryName="Kotlin" temporary="true">
|
||||
<option name="MAIN_CLASS_NAME" value="org.jetbrains.kotlin.examples.actors.namespace" />
|
||||
<option name="VM_PARAMETERS" />
|
||||
<option name="PROGRAM_PARAMETERS" />
|
||||
<option name="WORKING_DIRECTORY" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<module name="actors" />
|
||||
<envs />
|
||||
<RunnerSettings RunnerId="Run" />
|
||||
<ConfigurationWrapper RunnerId="Run" />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
|
||||
<module name="" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m" />
|
||||
<option name="PROGRAM_PARAMETERS" />
|
||||
<method>
|
||||
<option name="AntTarget" enabled="false" />
|
||||
<option name="BuildArtifacts" enabled="false" />
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="Maven.BeforeRunTask" enabled="false" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="Remote" factoryName="Remote">
|
||||
<option name="USE_SOCKET_TRANSPORT" value="true" />
|
||||
<option name="SERVER_MODE" value="false" />
|
||||
<option name="SHMEM_ADDRESS" value="javadebug" />
|
||||
<option name="HOST" value="localhost" />
|
||||
<option name="PORT" value="5005" />
|
||||
<method>
|
||||
<option name="AntTarget" enabled="false" />
|
||||
<option name="BuildArtifacts" enabled="false" />
|
||||
<option name="Maven.BeforeRunTask" enabled="false" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="JetRunConfigurationType" factoryName="Kotlin">
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="VM_PARAMETERS" />
|
||||
<option name="PROGRAM_PARAMETERS" />
|
||||
<option name="WORKING_DIRECTORY" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<module name="actors" />
|
||||
<envs />
|
||||
<method>
|
||||
<option name="AntTarget" enabled="false" />
|
||||
<option name="BuildArtifacts" enabled="false" />
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="Maven.BeforeRunTask" enabled="false" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="TestNG" factoryName="TestNG">
|
||||
<module name="" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<option name="SUITE_NAME" />
|
||||
<option name="PACKAGE_NAME" />
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="METHOD_NAME" />
|
||||
<option name="GROUP_NAME" />
|
||||
<option name="TEST_OBJECT" value="CLASS" />
|
||||
<option name="VM_PARAMETERS" value="-ea" />
|
||||
<option name="PARAMETERS" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="OUTPUT_DIRECTORY" />
|
||||
<option name="ANNOTATION_TYPE" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="moduleWithDependencies" />
|
||||
</option>
|
||||
<option name="USE_DEFAULT_REPORTERS" value="false" />
|
||||
<option name="PROPERTIES_FILE" />
|
||||
<envs />
|
||||
<properties />
|
||||
<listeners />
|
||||
<method>
|
||||
<option name="AntTarget" enabled="false" />
|
||||
<option name="BuildArtifacts" enabled="false" />
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="Maven.BeforeRunTask" enabled="false" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="Applet" factoryName="Applet">
|
||||
<module name="" />
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="HTML_FILE_NAME" />
|
||||
<option name="HTML_USED" value="false" />
|
||||
<option name="WIDTH" value="400" />
|
||||
<option name="HEIGHT" value="300" />
|
||||
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
|
||||
<option name="VM_PARAMETERS" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<method>
|
||||
<option name="AntTarget" enabled="false" />
|
||||
<option name="BuildArtifacts" enabled="false" />
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="Maven.BeforeRunTask" enabled="false" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="Application" factoryName="Application">
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="VM_PARAMETERS" />
|
||||
<option name="PROGRAM_PARAMETERS" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<option name="ENABLE_SWING_INSPECTOR" value="false" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<module name="" />
|
||||
<envs />
|
||||
<method>
|
||||
<option name="AntTarget" enabled="false" />
|
||||
<option name="BuildArtifacts" enabled="false" />
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="Maven.BeforeRunTask" enabled="false" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="JUnit" factoryName="JUnit">
|
||||
<module name="" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<option name="PACKAGE_NAME" />
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="METHOD_NAME" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea" />
|
||||
<option name="PARAMETERS" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="moduleWithDependencies" />
|
||||
</option>
|
||||
<envs />
|
||||
<patterns />
|
||||
<method>
|
||||
<option name="AntTarget" enabled="false" />
|
||||
<option name="BuildArtifacts" enabled="false" />
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="Maven.BeforeRunTask" enabled="false" />
|
||||
</method>
|
||||
</configuration>
|
||||
<list size="1">
|
||||
<item index="0" class="java.lang.String" itemvalue="Kotlin.org.jetbrains.kotlin.examples.actors" />
|
||||
</list>
|
||||
<configuration name="<template>" type="WebApp" default="true" selected="false">
|
||||
<Host>localhost</Host>
|
||||
<Port>5050</Port>
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="ShelveChangesManager" show_recycled="false" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="9624598b-68cd-4d51-9271-5ac61ef5a43a" name="Default" comment="" />
|
||||
<created>1328866126960</created>
|
||||
<updated>1328866126960</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="0" y="22" width="1440" height="874" extended-state="6" />
|
||||
<editor active="true" />
|
||||
<layout>
|
||||
<window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<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="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="CodeWindow" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32897604" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Gradle" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.18175288" sideWeight="0.50199205" order="0" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.49800798" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="ResolveWindow" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<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" content_ui="tabs" />
|
||||
<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" content_ui="tabs" />
|
||||
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
|
||||
<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" content_ui="tabs" />
|
||||
</layout>
|
||||
</component>
|
||||
<component name="VcsContentAnnotationSettings">
|
||||
<option name="myLimit" value="2678400000" />
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true" />
|
||||
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="true" />
|
||||
<option name="CHECK_NEW_TODO" value="true" />
|
||||
<option name="myTodoPanelSettings">
|
||||
<value>
|
||||
<are-packages-shown value="false" />
|
||||
<are-modules-shown value="false" />
|
||||
<flatten-packages value="false" />
|
||||
<is-autoscroll-to-source value="false" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="PERFORM_UPDATE_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_COMMIT_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_EDIT_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_CHECKOUT_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_ADD_REMOVE_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_ROLLBACK_IN_BACKGROUND" value="false" />
|
||||
<option name="CHECK_LOCALLY_CHANGED_CONFLICTS_IN_BACKGROUND" value="false" />
|
||||
<option name="ENABLE_BACKGROUND_PROCESSES" value="false" />
|
||||
<option name="CHANGED_ON_SERVER_INTERVAL" value="60" />
|
||||
<option name="SHOW_ONLY_CHANGED_IN_SELECTION_DIFF" value="true" />
|
||||
<option name="CHECK_COMMIT_MESSAGE_SPELLING" value="true" />
|
||||
<option name="DEFAULT_PATCH_EXTENSION" value="patch" />
|
||||
<option name="SHORT_DIFF_HORISONTALLY" value="true" />
|
||||
<option name="SHORT_DIFF_EXTRA_LINES" value="2" />
|
||||
<option name="SOFT_WRAPS_IN_SHORT_DIFF" value="true" />
|
||||
<option name="INCLUDE_TEXT_INTO_PATCH" value="false" />
|
||||
<option name="INCLUDE_TEXT_INTO_SHELF" value="false" />
|
||||
<option name="CREATE_PATCH_EXPAND_DETAILS_DEFAULT" value="true" />
|
||||
<option name="SHOW_FILE_HISTORY_DETAILS" value="true" />
|
||||
<option name="FORCE_NON_EMPTY_COMMENT" value="false" />
|
||||
<option name="LAST_COMMIT_MESSAGE" />
|
||||
<option name="MAKE_NEW_CHANGELIST_ACTIVE" value="false" />
|
||||
<option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
|
||||
<option name="CHECK_FILES_UP_TO_DATE_BEFORE_COMMIT" value="false" />
|
||||
<option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false" />
|
||||
<option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" />
|
||||
<option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8" />
|
||||
<option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5" />
|
||||
<option name="ACTIVE_VCS_NAME" />
|
||||
<option name="UPDATE_GROUP_BY_PACKAGES" value="false" />
|
||||
<option name="UPDATE_GROUP_BY_CHANGELIST" value="false" />
|
||||
<option name="SHOW_FILE_HISTORY_AS_TREE" value="false" />
|
||||
<option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager />
|
||||
</component>
|
||||
<component name="antWorkspaceConfiguration">
|
||||
<option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
|
||||
<option name="FILTER_TARGETS" value="false" />
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/src/Main.kt">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="32" column="57" selection-start="881" selection-end="881" vertical-scroll-proportion="1.3675214">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</component>
|
||||
<component name="masterDetails">
|
||||
<states>
|
||||
<state key="ArtifactsStructureConfigurable.UI">
|
||||
<settings>
|
||||
<artifact-editor />
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
<state key="FacetStructureConfigurable.UI">
|
||||
<settings>
|
||||
<last-edited>No facets are configured</last-edited>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
<state key="GlobalLibrariesConfigurable.UI">
|
||||
<settings>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
<state key="JdkListConfigurable.UI">
|
||||
<settings>
|
||||
<last-edited>1.6</last-edited>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
<state key="ModuleStructureConfigurable.UI">
|
||||
<settings>
|
||||
<last-edited>actors</last-edited>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
<state key="ProjectJDKs.UI">
|
||||
<settings>
|
||||
<last-edited>1.6</last-edited>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
<state key="ProjectLibrariesConfigurable.UI">
|
||||
<settings>
|
||||
<last-edited>KotlinRuntime</last-edited>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
</states>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
package org.jetbrains.kotlin.examples.actors
|
||||
|
||||
import std.concurrent.*
|
||||
import std.util.*
|
||||
|
||||
import java.util.concurrent.*
|
||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
import java.util.Date
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
/*
|
||||
Message handling class which process only one message at any given moment
|
||||
|
||||
Three main ways to use it
|
||||
- post and forget
|
||||
- post and await result
|
||||
- post and assign callback to be called when message processed
|
||||
*/
|
||||
abstract class Actor(protected val executor: Executor, val fair: Boolean = false) {
|
||||
private val queue = Ref()
|
||||
|
||||
class Ref() : AtomicReference<FunctionalQueue<Any>>(emptyQueue), Runnable {
|
||||
override fun run() {
|
||||
if (!fair)
|
||||
runUnfair()
|
||||
else
|
||||
runFair()
|
||||
}
|
||||
|
||||
private fun runFair() {
|
||||
while(true) {
|
||||
val q = get()
|
||||
if(q.identityEquals(busyEmptyQueue)) {
|
||||
if(compareAndSet(busyEmptyQueue, emptyQueue)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
else {
|
||||
val removed = q.removeFirst()
|
||||
val newQueue = if(removed._2.empty) busyEmptyQueue else removed._2
|
||||
if(compareAndSet(q, newQueue)) {
|
||||
doProcess(removed._1)
|
||||
executor.execute(this)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun runUnfair() {
|
||||
while (true) {
|
||||
val q = get()
|
||||
if(q.identityEquals(busyEmptyQueue)) {
|
||||
if (compareAndSet(q, emptyQueue)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (compareAndSet(q, busyEmptyQueue)) {
|
||||
var l = q.output
|
||||
while (!l.empty) {
|
||||
doProcess(l.head)
|
||||
l = l.tail
|
||||
}
|
||||
l = q.input.reversed()
|
||||
while (!l.empty) {
|
||||
doProcess(l.head)
|
||||
l = l.tail
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String? = null
|
||||
}
|
||||
|
||||
/*
|
||||
Handle message and return result
|
||||
This method guaranteed to be executed only one per object at any given time
|
||||
*/
|
||||
protected abstract fun onMessage(message: Any) : Any?
|
||||
|
||||
/*
|
||||
Post message to the actor.
|
||||
The method returns immediately and the message itself will be processed later
|
||||
*/
|
||||
fun post(message: Any) {
|
||||
messagesSent.incrementAndGet()
|
||||
while(true) {
|
||||
val q = queue.get()
|
||||
val newQueue = (if (q.identityEquals(busyEmptyQueue)) emptyQueue else q) add message
|
||||
if(queue.compareAndSet(q, newQueue)) {
|
||||
if (q.identityEquals(emptyQueue)) {
|
||||
executor.execute(queue)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun postFirst(message: Any) {
|
||||
messagesSent.incrementAndGet()
|
||||
while(true) {
|
||||
val q = queue.get()
|
||||
val newQueue = (if (q.identityEquals(busyEmptyQueue)) emptyQueue else q) addFirst message
|
||||
if(queue.compareAndSet(q, newQueue)) {
|
||||
if (q.identityEquals(emptyQueue)) {
|
||||
executor.execute(queue)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Post message to the actor and schedule callback to be executed on given executor when message processed
|
||||
*/
|
||||
fun post(message: Any, executor: Executor = this.executor, callback: (Any?)->Unit) =
|
||||
post(Callback(message, executor, callback))
|
||||
|
||||
/*
|
||||
Send message to the actor and await result
|
||||
*/
|
||||
fun send(message: Any) : Any? {
|
||||
val request = Request(message)
|
||||
post(request)
|
||||
request.await()
|
||||
return request.result
|
||||
}
|
||||
|
||||
private fun doProcess(message: Any) {
|
||||
messagesProcessed.incrementAndGet()
|
||||
when(message) {
|
||||
is Request -> {
|
||||
message.result = onMessage(message.message)
|
||||
message.countDown()
|
||||
}
|
||||
is Callback -> {
|
||||
val result = onMessage(message.message)
|
||||
message.executor execute {
|
||||
val callback = message.callback;
|
||||
callback(result)
|
||||
}
|
||||
}
|
||||
else -> onMessage(message)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Create actor on the same executor
|
||||
*/
|
||||
fun actor(handler: (Any)->Any?) = executor.actor(handler)
|
||||
|
||||
class object {
|
||||
val emptyQueue = FunctionalQueue<Any>()
|
||||
val busyEmptyQueue = FunctionalQueue<Any>() add "busy empty queue"
|
||||
|
||||
class Request(val message: Any) : java.util.concurrent.CountDownLatch(1) {
|
||||
var result: Any? = null
|
||||
}
|
||||
|
||||
class Callback(val message: Any, val executor: Executor, val callback: (Any?) -> Unit)
|
||||
|
||||
val messagesSent = AtomicLong()
|
||||
val messagesProcessed = AtomicLong()
|
||||
|
||||
val timer = fixedRateTimer(daemon=true, period=5000.lng) {
|
||||
val sent = messagesSent.get()
|
||||
val received = messagesProcessed.get()
|
||||
println("Actors stat: Sent: $sent Processed: $received Pending: ${sent-received}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Executor.actor(handler: (Any)->Any?) : Actor = object: Actor(this) {
|
||||
override fun onMessage(message: Any) {
|
||||
handler(message)
|
||||
}
|
||||
}
|
||||
|
||||
fun singleThreadActor(handler: (Any)->Any?) : Actor = Executors.newSingleThreadExecutor().sure().actor(handler)
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.jetbrains.kotlin.examples.actors
|
||||
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val numberOfSymbols = 10000
|
||||
val numberOfShards = 10
|
||||
val numberOfClients = 100000
|
||||
val stocksPerClient = 4
|
||||
|
||||
val stockServer = StockServer(numberOfShards)
|
||||
|
||||
for (i in 0..numberOfSymbols)
|
||||
stockServer post RegisterStock(i.toString())
|
||||
|
||||
println("Stock server started")
|
||||
|
||||
val executor = Executors.newFixedThreadPool(4*Runtime.getRuntime().sure().availableProcessors()).sure()
|
||||
|
||||
for(i in 0..numberOfClients) {
|
||||
val client = executor.actor{ message ->
|
||||
// println(message)
|
||||
}
|
||||
|
||||
for (k in 1..stocksPerClient) {
|
||||
val stock = (Math.random() * numberOfSymbols).int
|
||||
stockServer post Subscribe(stock.toString(), client)
|
||||
}
|
||||
}
|
||||
|
||||
println("clients connected")
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.jetbrains.kotlin.examples.actors
|
||||
|
||||
import std.concurrent.*
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.LinkedList
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.HashMap
|
||||
import java.util.HashSet
|
||||
|
||||
open class StockMessage(val symbol: String) {
|
||||
class object {
|
||||
val UpdateModel = "update"
|
||||
val DoUpdateModel = "do update"
|
||||
}
|
||||
}
|
||||
|
||||
class RegisterStock(symbol: String) : StockMessage(symbol)
|
||||
|
||||
class Subscribe(symbol: String, val subscriber: Actor) : StockMessage(symbol)
|
||||
|
||||
class Unsubscribe(symbol: String, val subscriber: Actor) : StockMessage(symbol)
|
||||
|
||||
class PriceUpdate(symbol: String, val price: Double) : StockMessage(symbol)
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.jetbrains.kotlin.examples.actors
|
||||
|
||||
import std.concurrent.*
|
||||
import org.jetbrains.kotlin.examples.actors.Actor
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.LinkedList
|
||||
|
||||
class StatCalculator() : Actor(Executors.newSingleThreadExecutor().sure()) {
|
||||
val list = LinkedList<Long> ()
|
||||
var average = 0.lng
|
||||
var sum = 0.lng
|
||||
var cnt = 0.lng
|
||||
|
||||
val timer = fixedRateTimer(period=2000.lng, daemon=true) {
|
||||
this@StatCalculator post "print"
|
||||
}
|
||||
|
||||
override fun onMessage(msg: Any) {
|
||||
when(msg) {
|
||||
is Long -> {
|
||||
list.add(msg)
|
||||
sum += msg
|
||||
if (list.size() > 20)
|
||||
sum -= list.removeFirst()
|
||||
average = sum / list.size()
|
||||
cnt++
|
||||
}
|
||||
"print" -> {
|
||||
println("Avr. period:[${average}ms] # updates:[$cnt]")
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.jetbrains.kotlin.examples.actors
|
||||
|
||||
import std.concurrent.*
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.LinkedList
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.HashMap
|
||||
import java.util.HashSet
|
||||
|
||||
class Stock(val symbol: String) {
|
||||
val subscribers = HashSet<Actor>()
|
||||
|
||||
var price = 10*Math.random()
|
||||
|
||||
fun update() {
|
||||
price += Math.random() - 0.5
|
||||
val priceUpdate = PriceUpdate(symbol, price)
|
||||
for(s in subscribers) {
|
||||
s post priceUpdate
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.jetbrains.kotlin.examples.actors
|
||||
|
||||
import std.concurrent.*
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.LinkedList
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.HashMap
|
||||
import java.util.HashSet
|
||||
|
||||
class StockServer(val numberOfShards : Int) : Actor(Executors.newFixedThreadPool(numberOfShards+1).sure()) {
|
||||
private val stockToServer = HashMap<String,StockServerShard> ()
|
||||
|
||||
private val statCalculator = StatCalculator()
|
||||
|
||||
private val shards = Array<StockServerShard> (numberOfShards, { (i: Int) -> StockServerShard(statCalculator, executor) })
|
||||
|
||||
private val timer = fixedRateTimer(period=1000.lng, daemon=true) {
|
||||
for(s in shards)
|
||||
s post StockMessage.UpdateModel
|
||||
}
|
||||
|
||||
override fun onMessage(message: Any): Unit {
|
||||
when (message) {
|
||||
is RegisterStock -> {
|
||||
val shard = shards[stockToServer.size() % shards.size]
|
||||
stockToServer.put(message.symbol, shard)
|
||||
shard post message
|
||||
}
|
||||
is Subscribe -> {
|
||||
stockToServer.get(message.symbol)?.post(message)
|
||||
}
|
||||
is Unsubscribe -> {
|
||||
stockToServer.get(message.symbol)?.post(message)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.jetbrains.kotlin.examples.actors
|
||||
|
||||
import std.concurrent.*
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.LinkedList
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.HashMap
|
||||
import java.util.HashSet
|
||||
|
||||
class StockServerShard(val statCalculator : StatCalculator, executor: Executor) : Actor(executor) {
|
||||
private val stocks = HashMap<String,Stock>();
|
||||
|
||||
private var previousTime = System.currentTimeMillis();
|
||||
|
||||
private var updateScheduled = false
|
||||
|
||||
override fun onMessage(message: Any) {
|
||||
when(message) {
|
||||
StockMessage.DoUpdateModel -> {
|
||||
val timeMillis = System.currentTimeMillis()
|
||||
for(s in stocks.values()) {
|
||||
s.update()
|
||||
}
|
||||
statCalculator post (timeMillis - previousTime)
|
||||
previousTime = timeMillis
|
||||
updateScheduled = false
|
||||
}
|
||||
StockMessage.UpdateModel -> {
|
||||
if (!updateScheduled) {
|
||||
this post StockMessage.DoUpdateModel
|
||||
updateScheduled = true
|
||||
}
|
||||
}
|
||||
is RegisterStock ->
|
||||
stocks.put(message.symbol, Stock(message.symbol))
|
||||
is Subscribe ->
|
||||
stocks.get(message.symbol)?.subscribers?.add(message.subscriber)
|
||||
is Unsubscribe ->
|
||||
stocks.get(message.symbol)?.subscribers?.add(message.subscriber)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user