jo 0.1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 344c02dfbdb2d8a82c5c49113764feb5536fe15f
4
+ data.tar.gz: d61d7fcff30a498de944e32f045e5b28a8ad3951
5
+ SHA512:
6
+ metadata.gz: 4faa2fdfa74959edc33a8e9a1c42b5491e9d71d534e6c088774af72d94c8f4312232dade20f8a89317b92f280da9e19c3ee0ce90924a2293a5efab4933f82beb
7
+ data.tar.gz: 89a87749068b2a3544444a1cb32aaaf4b2a5ce07f0ad140f3cf017394895eef55cb3d44cdfd203d0809e0559a296331c3ecdb38b25cc01ecdfc183ef4be01ce7
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Charles Oliver Nutter
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,58 @@
1
+ # Jo
2
+
3
+ A library to provide "goroutines", "channels", and "select" as in Go.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'jo'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install jo
18
+
19
+ ## Usage
20
+
21
+ require 'jo'
22
+
23
+ include Jo
24
+
25
+ # pinger ponger printer
26
+ def pinger(c)
27
+ 20.times do
28
+ c << 'ping'
29
+ end
30
+ end
31
+
32
+ def ponger(c)
33
+ 20.times do
34
+ c << 'pong'
35
+ end
36
+ end
37
+
38
+ def printer(c)
39
+ 40.times do
40
+ puts c.take
41
+ sleep 1
42
+ end
43
+ end
44
+
45
+ c = chan
46
+ jo {pinger(c)}
47
+ jo {ponger(c)}
48
+ jo {printer(c)}
49
+
50
+ gets # prevent exit
51
+
52
+ ## Contributing
53
+
54
+ 1. Fork it
55
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
56
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
57
+ 4. Push to the branch (`git push origin my-new-feature`)
58
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,30 @@
1
+ require 'jo'
2
+
3
+ include Jo
4
+
5
+ # pinger ponger printer
6
+ def pinger(c)
7
+ 20.times do
8
+ c << 'ping'
9
+ end
10
+ end
11
+
12
+ def ponger(c)
13
+ 20.times do
14
+ c << 'pong'
15
+ end
16
+ end
17
+
18
+ def printer(c)
19
+ 40.times do
20
+ puts c.take
21
+ sleep 1
22
+ end
23
+ end
24
+
25
+ c = chan
26
+ jo {pinger(c)}
27
+ jo {ponger(c)}
28
+ jo {printer(c)}
29
+
30
+ gets
@@ -0,0 +1,15 @@
1
+ require 'jo'
2
+
3
+ include Jo
4
+
5
+ # print out 1-10 in ten joroutines with 0-250ms delay
6
+ def f(n)
7
+ 10.times do |i|
8
+ puts "#{n}:#{i}"
9
+ sleep rand(250)/1000.0
10
+ end
11
+ end
12
+
13
+ 10.times do |n|
14
+ jo {f(n)}
15
+ end
@@ -0,0 +1,27 @@
1
+ require 'jo'
2
+
3
+ include Jo
4
+
5
+ c1 = chan
6
+ c2 = chan
7
+
8
+ jo do
9
+ loop do
10
+ c1 << "from 1"
11
+ sleep 2
12
+ end
13
+ end
14
+
15
+ jo do
16
+ loop do
17
+ c2 << "from 2"
18
+ sleep 3
19
+ end
20
+ end
21
+
22
+ loop do
23
+ select(
24
+ c1 => proc{|n| puts "even: #{n}"},
25
+ c2 => proc{|n| puts "odd: #{n}"}
26
+ )
27
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jo/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jo"
8
+ spec.version = Jo::VERSION
9
+ spec.authors = ["Charles Oliver Nutter"]
10
+ spec.email = ["headius@headius.com"]
11
+ spec.description = "An implementation of goroutines and channels for Ruby"
12
+ spec.summary = "An implementation of goroutines and channels (from the Go language) for Ruby"
13
+ spec.homepage = "https://github.com/headius/jo"
14
+ spec.license = "MIT"
15
+ spec.platform = "java"
16
+
17
+ spec.files = `git ls-files`.split($/) + ["target/jo-#{Jo::VERSION}.jar"]
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib", "target"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ end
@@ -0,0 +1,4 @@
1
+ require "jo/version"
2
+ require "jo-#{Jo::VERSION}.jar"
3
+
4
+ com.headius.jo.JoLibrary.new.load(JRuby.runtime, false)
@@ -0,0 +1,3 @@
1
+ module Jo
2
+ VERSION = "0.1"
3
+ end
data/pom.xml ADDED
@@ -0,0 +1,30 @@
1
+ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
+ <modelVersion>4.0.0</modelVersion>
4
+
5
+ <groupId>com.headius</groupId>
6
+ <artifactId>jo</artifactId>
7
+ <version>0.1</version>
8
+ <packaging>jar</packaging>
9
+
10
+ <name>jo</name>
11
+ <url>http://maven.apache.org</url>
12
+
13
+ <properties>
14
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15
+ </properties>
16
+
17
+ <dependencies>
18
+ <dependency>
19
+ <groupId>junit</groupId>
20
+ <artifactId>junit</artifactId>
21
+ <version>3.8.1</version>
22
+ <scope>test</scope>
23
+ </dependency>
24
+ <dependency>
25
+ <groupId>org.jruby</groupId>
26
+ <artifactId>jruby</artifactId>
27
+ <version>1.7.4</version>
28
+ </dependency>
29
+ </dependencies>
30
+ </project>
@@ -0,0 +1,156 @@
1
+ package com.headius.jo;
2
+
3
+ import java.io.IOException;
4
+ import java.util.Set;
5
+ import java.util.concurrent.BlockingQueue;
6
+ import java.util.concurrent.Callable;
7
+ import java.util.concurrent.ExecutionException;
8
+ import java.util.concurrent.ExecutorService;
9
+ import java.util.concurrent.Executors;
10
+ import java.util.concurrent.Future;
11
+ import java.util.concurrent.SynchronousQueue;
12
+ import java.util.concurrent.ThreadFactory;
13
+ import org.jruby.Finalizable;
14
+ import org.jruby.Ruby;
15
+ import org.jruby.RubyClass;
16
+ import org.jruby.RubyHash;
17
+ import org.jruby.RubyKernel;
18
+ import org.jruby.RubyModule;
19
+ import org.jruby.RubyObject;
20
+ import org.jruby.RubyString;
21
+ import org.jruby.anno.JRubyMethod;
22
+ import org.jruby.exceptions.RaiseException;
23
+ import org.jruby.runtime.Block;
24
+ import org.jruby.runtime.ObjectAllocator;
25
+ import org.jruby.runtime.ThreadContext;
26
+ import org.jruby.runtime.builtin.IRubyObject;
27
+ import org.jruby.runtime.load.Library;
28
+
29
+ public class JoLibrary implements Library{
30
+ public void load(Ruby runtime, boolean wrap) throws IOException {
31
+ RubyModule jo = runtime.defineModule("Jo");
32
+ final ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
33
+ public Thread newThread(Runnable r) {
34
+ Thread t = new Thread(r);
35
+ t.setDaemon(true);
36
+ return t;
37
+ }
38
+ });
39
+ jo.setInternalVariable("executor", executor);
40
+ RubyClass joFuture = runtime.defineClass("Future", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
41
+ RubyClass joChannel = runtime.defineClass("Channel", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
42
+
43
+ jo.defineAnnotatedMethods(JoMethods.class);
44
+ joFuture.defineAnnotatedMethods(JoFuture.class);
45
+ joChannel.defineAnnotatedMethods(JoChannel.class);
46
+
47
+ runtime.addFinalizer(new Finalizable() {
48
+ public void finalize() {
49
+ executor.shutdown();
50
+ }
51
+ });
52
+ }
53
+
54
+ public static class JoRoutine implements Callable<IRubyObject> {
55
+ public JoRoutine(Ruby runtime, Block body) {
56
+ this.runtime = runtime;
57
+ this.body = body;
58
+ }
59
+
60
+ public IRubyObject call() throws Exception {
61
+ ThreadContext context = runtime.getCurrentContext();
62
+ try {
63
+ return body.call(context);
64
+ } catch (RaiseException re) {
65
+ RubyKernel.puts(context, body.getBinding().getSelf(), new IRubyObject[] {
66
+ RubyString.newString(runtime, "joroutine terminated with error: " + re.getMessage())});
67
+ RubyKernel.puts(context, body.getBinding().getSelf(), new IRubyObject[] {re.getException().backtrace()});
68
+ throw re;
69
+ }
70
+ }
71
+
72
+ private final Ruby runtime;
73
+ private final Block body;
74
+ }
75
+
76
+ public static class JoChannel extends RubyObject {
77
+ public JoChannel(Ruby runtime, RubyClass klass, BlockingQueue<IRubyObject> queue) {
78
+ super(runtime, klass);
79
+ this.queue = queue;
80
+ }
81
+
82
+ @JRubyMethod(name = "<<")
83
+ public IRubyObject append(ThreadContext context, IRubyObject value) throws InterruptedException {
84
+ queue.put(value);
85
+ return this;
86
+ }
87
+
88
+ @JRubyMethod
89
+ public IRubyObject take(ThreadContext context) throws InterruptedException {
90
+ return queue.take();
91
+ }
92
+
93
+ private final BlockingQueue<IRubyObject> queue;
94
+ }
95
+
96
+ public static class JoFuture extends RubyObject {
97
+ public JoFuture(Ruby runtime, RubyClass klass, Future<IRubyObject> future) {
98
+ super(runtime, klass);
99
+
100
+ this.future = future;
101
+ }
102
+
103
+ @JRubyMethod
104
+ public IRubyObject get(ThreadContext context) throws ExecutionException, InterruptedException {
105
+ return future.get();
106
+ }
107
+
108
+ @JRubyMethod
109
+ public IRubyObject cancel(ThreadContext context) {
110
+ return context.runtime.newBoolean(future.cancel(true));
111
+ }
112
+
113
+ private final Future<IRubyObject> future;
114
+ }
115
+
116
+ public static class JoMethods {
117
+ @JRubyMethod(module = true)
118
+ public static IRubyObject jo(ThreadContext context, IRubyObject self, Block block) {
119
+ Ruby runtime = context.runtime;
120
+ RubyModule jo = runtime.getModule("Jo");
121
+ ExecutorService executor = (ExecutorService)jo.getInternalVariable("executor");
122
+ Future<IRubyObject> future = executor.submit(new JoRoutine(runtime, block));
123
+ return new JoFuture(runtime, jo.getClass("Future"), future);
124
+ }
125
+
126
+ @JRubyMethod(module = true)
127
+ public static IRubyObject chan(ThreadContext context, IRubyObject self, Block block) {
128
+ Ruby runtime = context.runtime;
129
+ return new JoChannel(runtime, (RubyClass)runtime.getClassFromPath("Jo::Channel"), new SynchronousQueue<IRubyObject>(true));
130
+ }
131
+
132
+ @JRubyMethod(module = true)
133
+ public static IRubyObject select(ThreadContext context, IRubyObject self, IRubyObject hash) {
134
+ Ruby runtime = context.runtime;
135
+ RubyHash cases = hash.convertToHash();
136
+
137
+ Set<RubyHash.RubyHashEntry> entries = (Set<RubyHash.RubyHashEntry>)cases.directEntrySet();
138
+ Object[] entryArray = entries.toArray();
139
+ OUTER: while (true) {
140
+ for (Object _entry : entryArray) {
141
+ RubyHash.RubyHashEntry entry = (RubyHash.RubyHashEntry)_entry;
142
+ IRubyObject _channel = (IRubyObject)entry.getKey();
143
+ if (!(_channel instanceof JoChannel)) throw runtime.newTypeError(_channel, runtime.getClassFromPath("Jo::Channel"));
144
+ IRubyObject _proc = (IRubyObject)entry.getValue();
145
+ IRubyObject value;
146
+ if ((value = ((JoChannel)_channel).queue.poll()) != null) {
147
+ _proc.callMethod(context, "call", value);
148
+ break OUTER;
149
+ }
150
+ Thread.yield();
151
+ }
152
+ }
153
+ return context.nil;
154
+ }
155
+ }
156
+ }
Binary file
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jo
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: java
6
+ authors:
7
+ - Charles Oliver Nutter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ prerelease: false
15
+ name: bundler
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '1.3'
21
+ type: :development
22
+ requirement: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ prerelease: false
29
+ name: rake
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: An implementation of goroutines and channels for Ruby
42
+ email:
43
+ - headius@headius.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - LICENSE.txt
49
+ - README.md
50
+ - Rakefile
51
+ - examples/pingpong.rb
52
+ - examples/randsleep.rb
53
+ - examples/selection.rb
54
+ - jo.gemspec
55
+ - lib/jo.rb
56
+ - lib/jo/version.rb
57
+ - pom.xml
58
+ - src/main/java/com/headius/jo/JoLibrary.java
59
+ - target/jo-0.1.jar
60
+ homepage: https://github.com/headius/jo
61
+ licenses:
62
+ - MIT
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ - target
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.0.3
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: An implementation of goroutines and channels (from the Go language) for Ruby
85
+ test_files: []