skynet 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/History.txt +99 -0
  2. data/Manifest.txt +10 -9
  3. data/README.txt +74 -7
  4. data/app_generators/skynet_install/skynet_install_generator.rb +26 -22
  5. data/app_generators/skynet_install/templates/migration.rb +11 -5
  6. data/app_generators/skynet_install/templates/skynet +25 -12
  7. data/app_generators/skynet_install/templates/skynet_schema.sql +56 -0
  8. data/bin/skynet +26 -2
  9. data/bin/skynet_install +24 -0
  10. data/bin/skynet_tuplespace_server +13 -0
  11. data/config/hoe.rb +1 -0
  12. data/lib/skynet.rb +3 -0
  13. data/lib/skynet/mapreduce_helper.rb +74 -0
  14. data/lib/skynet/message_queue_adapters/mysql.rb +225 -172
  15. data/lib/skynet/message_queue_adapters/tuple_space.rb +31 -16
  16. data/lib/skynet/skynet_active_record_extensions.rb +78 -46
  17. data/lib/skynet/skynet_config.rb +162 -23
  18. data/lib/skynet/skynet_console.rb +23 -10
  19. data/lib/skynet/skynet_console_helper.rb +61 -58
  20. data/lib/skynet/skynet_job.rb +741 -493
  21. data/lib/skynet/skynet_launcher.rb +5 -1
  22. data/lib/skynet/skynet_manager.rb +106 -49
  23. data/lib/skynet/skynet_message.rb +169 -174
  24. data/lib/skynet/skynet_message_queue.rb +29 -16
  25. data/lib/skynet/skynet_partitioners.rb +92 -0
  26. data/lib/skynet/skynet_ruby_extensions.rb +3 -4
  27. data/lib/skynet/skynet_task.rb +61 -19
  28. data/lib/skynet/skynet_tuplespace_server.rb +0 -2
  29. data/lib/skynet/skynet_worker.rb +73 -51
  30. data/lib/skynet/version.rb +1 -1
  31. data/test/test_active_record_extensions.rb +138 -0
  32. data/test/test_helper.rb +6 -0
  33. data/test/{mysql_message_queue_adaptor_test.rb → test_mysql_message_queue_adapter.rb} +94 -30
  34. data/test/test_skynet.rb +11 -11
  35. data/test/test_skynet_install_generator.rb +0 -4
  36. data/test/test_skynet_job.rb +717 -0
  37. data/test/test_skynet_manager.rb +142 -0
  38. data/test/test_skynet_message.rb +229 -0
  39. data/test/test_skynet_task.rb +24 -0
  40. data/test/{tuplespace_message_queue_test.rb → test_tuplespace_message_queue.rb} +25 -30
  41. data/website/index.html +56 -16
  42. data/website/index.txt +55 -25
  43. data/website/template.rhtml +1 -1
  44. metadata +29 -13
  45. data/app_generators/skynet_install/templates/skynet_console +0 -16
  46. data/bin/skynet_console +0 -9
  47. data/sometest.rb +0 -23
  48. data/test/all_models_test.rb +0 -139
  49. data/test/skynet_manager_test.rb +0 -107
  50. data/test/skynet_message_test.rb +0 -42
  51. data/tmtags +0 -1242
data/History.txt CHANGED
@@ -1,3 +1,102 @@
1
+ == 0.9.2 2008-01-22
2
+ Highlights:
3
+ - Multiple Message Queues
4
+ - Many more Job options including options to control how jobs are distributed.
5
+ - The various options for how a job is run has been made much clearer.
6
+ - The Mysql Message Queue Adapter has been optimized and made more reliable.
7
+ - You can now control how many times skynet retries failed master, map and reduce tasks.
8
+ - Large data sets can now be streamed to the queue.
9
+
10
+ Details:
11
+
12
+ Active::Record#distributed_find
13
+ - Active Record distributed_find now handles REALLY large sets by breaking them into seperate jobs. 1MM models per master broken into ranges of 1000.
14
+
15
+ Skynet::Job
16
+ - code path through Skynet::Job is now clear. There are 3 ways to run Skynet::Job. Local Master (default), Remote Master, Async (implies remote master)
17
+ - Skynet::Job supports keep_map_tasks and keep_reduce_tasks settings.
18
+ If true, the master will run the tasks locally.
19
+ If a number is provided, the master will run the tasks locally if there are LESS THAN OR EQUAL TO the number provided
20
+ There are also Skynet::CONFIG settings for defaults. DEFAULT_KEEP_REDUCE_TASKS, DEFAULT_KEEP_MAP_TASKS
21
+ I can see there being a problem with the timeouts being a little off... Since your kinda in a master and kinda in a map or reduce timeout. The task timeouts will be correct at least. Though, you won't get the benefit of redoes yet.
22
+ - Skynet::Job now supports setting RETRY times per job by MASTER, MAP and REDUCE. So you can have a MASTER_RETRY=0, but have MAP_RETRY=2 and REDUCE_RETRY=3. There are now defaults for those as well :DEFAULT_MASTER_RETRY, :DEFAULT_MAP_RETRY, :DEFAULT_REDUCE_RETRY. If a message passes its RETRY it will be marked with an iteration of -1. delete_expired_messages removes those messages as well. These show up in the stats as :failed_tasks. Skynet::Task and Skynet::Message now have retry fields denoting the maximum number of retries.
23
+ - You can now pass queue_id or queue to Skynet::Job
24
+ - There is now a :MAX_RETRIES config setting that controls how many iterations Skynet will even look for tasks as well.
25
+ - You can now stream map_data to the queue by passing an Enumerable for your map_data
26
+ - Refactored Skynet::Job to be much cleaner and easier to test.
27
+ - Skynet::Job now has access to a local queue which it can treat almost like the real one.
28
+ - deprecate Skynet::Job#run_master
29
+ - rename reduce_partitioner method to just reduce_partition
30
+ - Skynet::Job has better support for running tasks locally. A job may run tasks in its own process if
31
+ you are running in solo mode, you've made a "single" job, or you set the keep_map_tasks or keep_reduce_tasks below.
32
+ When a job runs tasks locally it now honors the retry settings and timeouts.
33
+ - Skynet::Job and Skynet::AsyncJob are now almost identical. In fact you can just use Skynet::Job and tell it to run async.
34
+ - Skynet::Job Changed map_tasks and reduce_tasks to mappers and reducers respectively. This was to remove the ambiguity between the actual map/reduce tasks and the number of mappers/reducers desired.
35
+ - Skynet::Jobs can not be told what queue to use for that job by passing :queue or :queue_id DEFAULT 0
36
+ - Skynet::Job won't call the reduce_partitioner if there are no valid results from the map_step.
37
+
38
+ MapreduceHelper mixin
39
+ - You can include MapreduceHelper into your class and then implement self.map_each and self.reduce_each methods. The included self.map and self.reduce methods will handle iterating over the map_data and reduce_data, passing each element to your map_each and reduce_each methods respectively. They will also handle error handling within that loop to make sure even if a single map or reduce fails, processing will continue. If you do not want processing to continue if a map fails, do not use the MapreduceHelper mixin.
40
+
41
+ Multiple Message Queues!
42
+ - Add the ability to have multiple message queues in the same table message_queue_table.
43
+ - You can start skynet with a --queue_id or --queue option to determine which queue workers should look in.
44
+ - Skynet::Jobs can not be told what queue to use for that job by passing :queue or :queue_id. DEFAULT 0
45
+ - Queues can be configred via Skynet::CONFIG[:MESSAGE_QUEUES] = [] which comes with an array of queues id 1 through 10 named "one" through "ten"
46
+
47
+ Skynet Console
48
+ - You now start the skynet console by running 'skynet console' at the command line. There is no longer a skynet_console app.
49
+ - The console now loads the configs that are in your local skynet script.
50
+
51
+ Skynet::Config
52
+ - Added Skynet.silent {} Runs your code with no debugging output.
53
+ - Made sure all config options for TupleSpace? adapter begin with TS and all Mysql adapter CONFIG settings start with MYSQL.
54
+ - There is now a :MAX_RETRIES config setting that controls how many iterations Skynet will even look for tasks as well.
55
+
56
+ Skynet::Partitioners
57
+ - Created a Skynet::Partitioners class where various partitioners can be found. To specify one of them merely provide that specific Skynet::Partitioners subclass as your reduce_partitioner in your Skynet::Job
58
+
59
+ Skynet Install
60
+ - skynet_install now has a --mysql option. This installs the migration as well as a skynet_schema.sql file.
61
+
62
+ Mysql Message Queue Adapter
63
+ - You can now configure your database options outside of rails with Skynet::CONFIG[:MYSQL_*] options.
64
+ - Mysql adapter now updates the updated_on time of rows in skynet_message_queues
65
+ - Fixed Mysql Message Adaptor to take_next_task safer and more efficiently. There seems to be far less risk of a race condition where two workers would take the same task.
66
+ - Eliminated 1 db update per every task taken making it MUCH more efficient.
67
+ - Skynet::MessageQueueAdaptor::Mysql now tries to reconnect if it gets disconnected. This was to solve the "Mysql Server has Gone Away" errors.
68
+ - Implemented version_active? in mysql message queue adapter. It's a way for workers to check to see if a version is still in the queue.
69
+
70
+ Skynet::Task
71
+ - Skynet::Task#master_task takes care of creating the master job and task now. I have mixed feelings about this.
72
+ - ENFORCED TIMEOUTS - Even though a master might give up on a worker if it didn't respond in time, there was nothing to step any given worker from running forever. We now enforce the timeouts (master_timeout, map_timeout, reduce_timeout) given in Skynet::Job using the Timeout module. This causes a Timeout::Error to be thrown. If you are using the mysql adapter, this can cause strange results sometimes. If the Timeout error is thrown during a DB query, ActiveRecord will throw an ActiveRecord::StatementInvalid exception which includes the Timeout::Error exception in it. Not sure how to prevent that from happening.
73
+
74
+ Skynet::Worker
75
+ - Workers now have a Skynet::CONFIG[:WORKER_MAX_PROCESSED] setting to control when to respawn based on how many that worker has processed.
76
+ - You can start skynet with a --queue_id or --queue option to determine which queue workers should look in.
77
+ - Workers do not restart until there are no more items in the queue of that version.
78
+
79
+ Skynet::Message
80
+ - Skynet::Message now stores fields as an array. It is far more efficient now as well.
81
+
82
+ Now 90% more Tests!
83
+
84
+ BUGFIXES
85
+ - Skynet Workers now restart properly when the worker_version changes.
86
+ - starting tuplespce_server, you no longer need to provide the --port if you're already providing the drburi-
87
+ - Fixed a bug where Skynet::MessageQueueAdapter::Mysql would sometimes pick up tasks another worker had already picked up.
88
+ - Fix bug in Skynet::Worker where it wouldn't die right if the max processed was reached.
89
+ - Workers were supposed to restart when the worker_version changed. They do that properly now.
90
+
91
+ Thanks to Jason Rimmer for finding these bugs.
92
+ - Fix bug in Skynet::Message where it would calculate the iteration improperly.
93
+ - The skynet gem appears to be missing the Rubigen dependency
94
+ - Running skynet_install even without the rails arg still generates code with rails dependencies and tailings: RAILS_ROOT, RAILS_ENV, and the various directory tailings such as 'db/migrate', etc.
95
+ - Generated skynet script is missing "require 'rubygems'"
96
+ - Specification of pid directory and file is incorrect as 'skynet_manager.rb' wants only a directory with it specifying the file
97
+ - The sleep while waiting to start the queue server isn't long enough. There is now a CONFIG setting TS_SERVER_START_DELAY.
98
+
99
+
1
100
  == 0.0.1 2007-12-16
2
101
 
3
102
  * 1 major enhancement:
data/Manifest.txt CHANGED
@@ -7,14 +7,14 @@ app_generators/skynet_install/USAGE
7
7
  app_generators/skynet_install/skynet_install_generator.rb
8
8
  app_generators/skynet_install/templates/migration.rb
9
9
  app_generators/skynet_install/templates/skynet
10
- app_generators/skynet_install/templates/skynet_console
10
+ app_generators/skynet_install/templates/skynet_schema.sql
11
11
  bin/skynet
12
- bin/skynet_console
13
12
  bin/skynet_install
14
13
  bin/skynet_tuplespace_server
15
14
  config/hoe.rb
16
15
  config/requirements.rb
17
16
  lib/skynet.rb
17
+ lib/skynet/mapreduce_helper.rb
18
18
  lib/skynet/mapreduce_test.rb
19
19
  lib/skynet/message_queue_adapters/message_queue_adapter.rb
20
20
  lib/skynet/message_queue_adapters/mysql.rb
@@ -31,6 +31,7 @@ lib/skynet/skynet_logger.rb
31
31
  lib/skynet/skynet_manager.rb
32
32
  lib/skynet/skynet_message.rb
33
33
  lib/skynet/skynet_message_queue.rb
34
+ lib/skynet/skynet_partitioners.rb
34
35
  lib/skynet/skynet_ruby_extensions.rb
35
36
  lib/skynet/skynet_task.rb
36
37
  lib/skynet/skynet_tuplespace_server.rb
@@ -44,20 +45,20 @@ script/destroy
44
45
  script/generate
45
46
  script/txt2html
46
47
  setup.rb
47
- sometest.rb
48
48
  tasks/deployment.rake
49
49
  tasks/environment.rake
50
50
  tasks/website.rake
51
- test/all_models_test.rb
52
- test/mysql_message_queue_adaptor_test.rb
53
- test/skynet_manager_test.rb
54
- test/skynet_message_test.rb
51
+ test/test_active_record_extensions.rb
55
52
  test/test_generator_helper.rb
56
53
  test/test_helper.rb
54
+ test/test_mysql_message_queue_adapter.rb
57
55
  test/test_skynet.rb
58
56
  test/test_skynet_install_generator.rb
59
- test/tuplespace_message_queue_test.rb
60
- tmtags
57
+ test/test_skynet_job.rb
58
+ test/test_skynet_manager.rb
59
+ test/test_skynet_message.rb
60
+ test/test_skynet_task.rb
61
+ test/test_tuplespace_message_queue.rb
61
62
  website/index.html
62
63
  website/index.txt
63
64
  website/javascripts/rounded_corners_lite.inc.js
data/README.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  Skynet
2
2
  http://skynet.rubyforge.org/
3
- by Adam Pisoni
3
+ by Adam Pisoni and Geni.com
4
4
 
5
5
  == DESCRIPTION:
6
6
 
@@ -8,6 +8,36 @@ Skynet is an open source Ruby implementation of Google's Map/Reduce framework, c
8
8
 
9
9
  Skynet is an adaptive, self-upgrading, fault-tolerant, and fully distributed system with no single point of failure. It uses a "peer recovery" system where workers watch out for each other. If a worker dies or fails for any reason, another worker will notice and pick up that task. Skynet also has no special 'master' servers, only workers which can act as a master for any task at any time. Even these master tasks can fail and will be picked up by other workers.
10
10
 
11
+ == DOCUMENTATION
12
+
13
+ Feel free to read on if you want more of an overview of Skynet with some specific examples. More specific documentation can be found here:
14
+
15
+ Skynet::Job - The main interface to Skynet
16
+
17
+ Skynet::Config - Configuration Options
18
+
19
+ bin/skynet[link:files/bin/skynet.html] - Starting Skynet
20
+
21
+ bin/skynet_install[link:files/bin/skynet_install.html] - Installing Skynet into a local project
22
+
23
+ == Map/Reduce
24
+
25
+ First of all, Skynet is merely a distributed computing system that allows you to follow the map/reduce steps. You don't have to use it as a map/reduce framework. You can use it as a simple distributed system, or even a simple asynchronous processing system.
26
+
27
+ If you already know what Map/Reduce is, skip this section.
28
+
29
+ If you want to know where all this Map/Reduce hype started, you should read Google's paper on it. http://labs.google.com/papers/mapreduce.html
30
+
31
+ When I first read that Google paper some years ago, I was a little confused about what all the hypes was. At the most basic level, it seemed too simple to be revolutionary. So you've got a job with 3 steps, you put some data in, it gets split out to a map step run no many machines, the returned data gets reshuffled and parceled out to a reduce step run on many machines. All the results are then put together again. You can see it as 5 steps actually. Data -> Partition -> Map -> Partition -> Reduce. Simple enough. Almost too simple. It was only years later when I began working on Skynet that I realize what the revolutionary part of Google's framwork was. It made distributed computing accessible. Any engineer could write a complex distributed system without needing to know about the complexities of such systems. Also, since the distributed system was generalized, you would only need one class of machines to run ALL of your distributed processing, instead of specialized machines for specialized functions. THAT was revolutionary.
32
+
33
+ There are a number of key differences between Google's MR system and skynet. Firstly, currently you can not actually send raw code to the workers. You are really only telling it where the code is. At first this bothered me a lot. Then I realized that in most OO systems, the amount of code you'd need duplicate and to send over the wire to every worker could be ridiculous. For example, if you want to distribute a task you need to run in Rails, you'd have to send almost all of your app and rails to every worker with every chunk of data. So, even if you COULD send code, you'd probably only be sending code that just called some other code in your system. If you can't send ALL the code it needs, then you might as well just tell it where the code is.
34
+
35
+ The second big difference is that Google's MR framework uses Master federater processes to dole out tasks, recombine them, and generally watch the system. Skynet has not such masters. Instead Skynet uses a standard message queue for all communication. That same message queue allows workers to watch each other in the same way a master would, but without the single point of failure (except the queue itself).
36
+
37
+ At its simplest level, a single map reduce job defines a data set, a map method and a reduce method. It may also define a partition method. The map/reduce server evenly splits up (partitions) the data given to it and sends those chunks of data, along with a copy of the code in the map method, to workers that execute the map method against the data it was given. The output from each worker is sent back to the map/reduce server. At this point the Mapreduce server evenly partitions the RESULT data returned from the workers and sends those chunks of data along with the reduce code to the workers to be executed. The reducers return the final result which is returned to whomever requested the job be done in the first place. Not all job need a reduce step, some may just have a map step.
38
+
39
+ The most common example of a mapreduce job is a distributed word counter. Say you wanted to determine how many times a single word appears in a 1GB text file. The map/reduce server would break up the 1GB file into reasonable chunks, say 100 lines per chunk (or partition) and then send each 100 line partition along with the code that looks for that word, to workers. Each worker would grab its partition of the data, count how many times the word appears in the data and return that number. It might take dozens of workers to complete the task. When the map step is done, you are left with a huge list of counts returned by the workers. In this example, the reduce step would involve sending that list of counts to another worker, with the code required to sum those counts and finally return the total. In this way a task that used to be done in a linear fashion can be parallelized easily.
40
+
11
41
  == INSTALLATION:
12
42
 
13
43
  Skynet can be installed via RubyGems:
@@ -15,6 +45,7 @@ Skynet can be installed via RubyGems:
15
45
  $ sudo gem install skynet
16
46
 
17
47
  == GETTING STARTED
48
+
18
49
  Skynet works by putting "tasks" on a message queue which are picked up by skynet workers, who execute the tasks, then put their results back on the message queue. Skynet works best when it runs with your code. For example, you might have a rails app and want some code you've already written to run asynchronously or in a distributed way. Skynet can run within your code by installing a skynet launcher into your app. Running this skynet launcher within your app guarantees all skynet workers will have access to your code. This will be covered later.
19
50
 
20
51
  Skynet currently supports 2 message queue systems, TupleSpace and Mysql. By default, the TupleSpace queue is used as it is the easiest to set up, though it is less powerful and less scaleable for large installations.
@@ -24,11 +55,16 @@ Since Skynet is a distributed system, it requires you have a skynet message queu
24
55
 
25
56
  $ skynet
26
57
 
27
- This starts a skynet tuple space message queue and 4 workers. You can now run the Skynet Console to play with skynet a little.
58
+ This starts a skynet tuple space message queue and 4 workers. You can now run the skynet console to play with skynet a little. See Skynet::ConsoleHelper for commands.
28
59
 
29
- $ skynet_console
60
+ $ skynet console
61
+
62
+ For help try:
63
+ $ skynet --help
64
+ or
65
+ $ skynet console --help
30
66
 
31
- Here are some commands you can run.
67
+ Here are some commands you can run in the skynet console.
32
68
  > stats
33
69
  > manager.worker_pids
34
70
  > [1,2,3,1,1,4].mapreduce(Skynet::MapreduceTest)
@@ -44,7 +80,7 @@ To be really useful, you'll want to run skynet in your own application. To do
44
80
  If you pass --rails it will assume it is installing in a rails app. Once it is installed in your application, you can run skynet with
45
81
 
46
82
  $ ./script/skynet
47
- $ ./script/skynet_console
83
+ $ ./script/skynet console
48
84
 
49
85
  == USAGE:
50
86
 
@@ -69,10 +105,41 @@ In the second example, once the objects of YourModel are distributed, each worke
69
105
 
70
106
  Sometimes you have a method you want to call on a model asynchronously. Using :send_later you can call a method, pass it options, and decide whether you want Skynet to save that model or not once its done calling your method.
71
107
 
72
- == EXAMPLES:
108
+ == Creating Skynet Jobs
73
109
 
74
- == LIMITATIONS:
110
+ The main interface to Skynet is through Skynet::AsyncJob or Skynet::Job
111
+
112
+ job = Skynet::AsyncJob.new(options)
113
+ job.run_master
114
+
115
+ There are many options you can pass or change once you have a job object. See Skynet::Job for more info.
75
116
 
117
+ Most of the time, you will only need to pass a map_reduce_class and map_data. All other options just give you finer grain control. map_data must be an array. The map_reduce_class must AT LEAST implement a self.map class method. It may also implement self.reduce, self.reduce_partitioner, and self.map_partitioner. Skynet will assume it can use all of those methods in the map_reduce_class you pass.
118
+
119
+ Your map and reduce class methods should ALWAYS assume they are being passed an array. Your map method must always return an array as well.
120
+
121
+ == CREDITS
122
+ There are a number of people who either directly or indirectly worked on Skynet.
123
+ John Beppu (wrote the original worker/manager code)
124
+ Justin Balthrop
125
+ Zack Parker
126
+ Amos Elliston
127
+ Zack Hobson
128
+ Alan Braverman
129
+ Mike Stangel
130
+ Scott Steadman
131
+ Andrew Arrow
132
+ Jason Rojas
133
+
134
+ Skynet was inspired by and heavily influenced by Josh Carter and this blog post.
135
+ http://multipart-mixed.com/software/simple_mapreduce_in_ruby.html
136
+
137
+ Also by Starfish by Lucas Carlson
138
+ http://tech.rufy.com/2006/08/mapreduce-for-ruby-ridiculously-easy.html
139
+ http://rufy.com/starfish/doc/
140
+
141
+ == CONTACT:
142
+ Adam Pisoni, Geni.com (apisoni at geni.com)
76
143
 
77
144
  == LICENSE:
78
145
 
@@ -3,13 +3,12 @@ class SkynetInstallGenerator < RubiGen::Base
3
3
  DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
4
4
  Config::CONFIG['ruby_install_name'])
5
5
 
6
- default_options :author => nil
7
- default_options :in_rails => nil
8
- default_options :include_migration => false
6
+ default_options :in_rails => false
7
+ default_options :mysql => false
9
8
 
10
9
  attr_reader :name
11
10
  attr_reader :in_rails
12
- attr_reader :include_migration
11
+ attr_reader :mysql
13
12
 
14
13
  def initialize(runtime_args, runtime_options = {})
15
14
  super
@@ -26,17 +25,16 @@ class SkynetInstallGenerator < RubiGen::Base
26
25
  BASEDIRS.each { |path| m.directory path }
27
26
 
28
27
  # Create stubs
29
- # m.template "template.rb", "some_file_after_erb.rb"
30
- m.template "skynet", "script/skynet", :assigns => {:rails => @rails}, :collision => :ask, :chmod => 0755, :shebang => options[:shebang]
31
- m.template "skynet_console", "script/skynet_console", :assigns => {:rails => @rails}, :collision => :ask, :chmod => 0755, :shebang => options[:shebang]
32
- if include_migration
28
+ m.template "skynet", "script/skynet", :collision => :ask, :chmod => 0775, :shebang => options[:shebang]
29
+ if @mysql
30
+ m.template "skynet_schema.sql", "db/skynet_schema.sql", :collision => :ask, :chmod => 0655
33
31
  m.directory 'db/migrate'
34
- m.migration_template "migration.rb", "db/migrate", :collision => :skip, :assigns => {
32
+ m.migration_template "migration.rb", "db/migrate",
33
+ :collision => :ask,
34
+ :assigns => {
35
35
  :migration_name => "CreateSkynetTables"
36
36
  }, :migration_file_name => "create_skynet_tables"
37
37
  end
38
- # m.dependency "install_rubigen_scripts", [destination_root, 'skynet_install'],
39
- # :shebang => options[:shebang], :collision => :force
40
38
  end
41
39
  end
42
40
 
@@ -45,7 +43,9 @@ class SkynetInstallGenerator < RubiGen::Base
45
43
  <<-EOS
46
44
  Creates a ...
47
45
 
48
- USAGE: #{spec.name} [--rails] directory (can be '.' for current)"
46
+ USAGE: #{spec.name} [--rails] [--mysql] directory (can be '.' for current)"
47
+ Installs:
48
+ ./script/skynet
49
49
  EOS
50
50
  end
51
51
 
@@ -54,31 +54,35 @@ EOS
54
54
  opts.separator 'Options:'
55
55
  # For each option below, place the default
56
56
  # at the top of the file next to "default_options"
57
- # opts.on("-a", "--author=\"Your Name\"", String,
58
- # "Some comment about this option",
59
- # "Default: none") { |options[:author]| }
60
57
  opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
61
- opts.on("--include-migration",
62
- "Include mysql migration if you want to use mysql as your message queue") { |options[:include_migration]| }
58
+ opts.on("--mysql",
59
+ "Include mysql migration if you want to use mysql as your message queue.
60
+ Installs:
61
+ ./db/skynet_schema.sql
62
+ ./db/migrate/db/migrate/###_create_skynet_tables.rb
63
+ ") do |mysql|
64
+ options[:mysql] = true if mysql
65
+ end
63
66
  opts.on("-r", "--rails",
64
67
  "Install into rails app",
65
- "Default: false") { |options[:rails]| }
68
+ "Default: false") do |rails|
69
+ options[:rails] = true if rails
70
+ end
66
71
  end
67
72
 
68
73
  def extract_options
69
74
  # for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
70
75
  # Templates can access these value via the attr_reader-generated methods, but not the
71
76
  # raw instance variable value.
72
- # @author = options[:author]
73
- @in_rails = options[:rails]
74
- @include_migration = options[:include_migration]
77
+ @in_rails = options[:rails]
78
+ @mysql = options[:mysql]
75
79
  end
76
80
 
77
81
  # Installation skeleton. Intermediate directories are automatically
78
82
  # created so don't sweat their absence here.
79
83
  BASEDIRS = %w(
84
+ db
80
85
  log
81
86
  script
82
- db/migrate
83
87
  )
84
88
  end
@@ -2,6 +2,7 @@ class <%= migration_name %> < ActiveRecord::Migration
2
2
  def self.up
3
3
  create_table :skynet_worker_queues do |t|
4
4
  t.column :id, "bigint unsigned primary key"
5
+ t.column :queue_id, :integer, :default => 0
5
6
  t.column :created_on, :timestamp
6
7
  t.column :updated_on, :timestamp
7
8
  t.column :tasktype, :string
@@ -21,6 +22,8 @@ class <%= migration_name %> < ActiveRecord::Migration
21
22
  end
22
23
  create_table :skynet_message_queues do |t|
23
24
  t.column :id, "bigint unsigned primary key"
25
+ t.column :queue_id, :integer, :default => 0
26
+ t.column :tran_id, "bigint unsigned"
24
27
  t.column :created_on, :timestamp
25
28
  t.column :updated_on, :timestamp
26
29
  t.column :tasktype, :string
@@ -34,22 +37,25 @@ class <%= migration_name %> < ActiveRecord::Migration
34
37
  t.column :iteration, :integer
35
38
  t.column :version, :integer
36
39
  t.column :timeout, "decimal(16,4)"
40
+ t.column :retry, :integer, :default => 0
37
41
  end
38
42
  create_table :skynet_queue_temperature do |t|
39
43
  t.column :id, "bigint unsigned primary key"
44
+ t.column :queue_id, :integer, :default => 0
40
45
  t.column :updated_on, :timestamp
41
46
  t.column :count, :integer, :default => 0
42
47
  t.column :temperature, "decimal(6,4) default 1"
43
48
  t.column :type, :string
44
49
  end
45
- add_index :skynet_message_queues, [:job_id]
50
+ add_index :skynet_message_queues, :job_id
46
51
  add_index :skynet_message_queues, :task_id
47
- add_index :skynet_message_queues, [:tasktype,:payload_type,:expire_time], :name => "index_skynet_mqueue_for_take"
52
+ add_index :skynet_message_queues, :tran_id, :unique => true
53
+ add_index :skynet_message_queues, [:queue_id,:tasktype,:payload_type,:expire_time], :name => "index_skynet_mqueue_for_take"
48
54
  add_index :skynet_worker_queues, [:hostname, :process_id]
49
55
  add_index :skynet_worker_queues, :worker_id, :unique=> true
50
- execute "insert into skynet_queue_temperature (type) values ('master')"
51
- execute "insert into skynet_queue_temperature (type) values ('any')"
52
- execute "insert into skynet_queue_temperature (type) values ('task')"
56
+ execute "insert into skynet_queue_temperature (queue_id,type) values (0,'master')"
57
+ execute "insert into skynet_queue_temperature (queue_id,type) values (0,'any')"
58
+ execute "insert into skynet_queue_temperature (queue_id,type) values (0,'task')"
53
59
  end
54
60
 
55
61
  def self.down
@@ -1,22 +1,35 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- <% if in_rails %>
3
+ <% if in_rails -%>
4
+ # Load your rails app
4
5
  require File.dirname(__FILE__) + '/../config/boot'
5
6
  require File.expand_path(File.dirname(__FILE__)) + '/../config/environment'
6
- <% end %>
7
+ <% end -%>
7
8
 
9
+ require 'rubygems'
8
10
  require 'skynet'
9
11
 
10
12
  Skynet::CONFIG[:LAUNCHER_PATH] = File.expand_path(__FILE__)
11
- Skynet::CONFIG[:SKYNET_LOG_FILE] = Logger::ERROR
12
- Skynet::CONFIG[:SKYNET_LOG_LEVEL] = Logger::ERROR
13
- <% if in_rails %>
14
- Skynet::CONFIG[:SKYNET_PIDS_FILE] = File.expand_path("../log/skynet.pid"),
15
- Skynet::CONFIG[:SKYNET_LOG_FILE] = File.expand_path("../log/skynet.log"),
16
- <% else %>
17
- Skynet::CONFIG[:SKYNET_PIDS_FILE] = File.expand_path("#{RAILS_ROOT}/log/skynet_#{RAILS_ENV}.pid"),
18
- Skynet::CONFIG[:SKYNET_LOG_FILE] = File.expand_path("#{RAILS_ROOT}/log/skynet_#{RAILS_ENV}.log"),
19
- <% end %>
13
+ Skynet::CONFIG[:SKYNET_LOG_FILE] ||= STDERR
14
+ Skynet::CONFIG[:SKYNET_LOG_LEVEL] ||= Logger::ERROR
15
+ <% if in_rails -%>
16
+ Skynet::CONFIG[:SKYNET_PIDS_FILE] ||= File.expand_path("#{RAILS_ROOT}/log/skynet_#{RAILS_ENV}.pid")
17
+ Skynet::CONFIG[:SKYNET_LOG_FILE] ||= File.expand_path("#{RAILS_ROOT}/log/skynet_#{RAILS_ENV}.log")
18
+ <% else -%>
19
+ Skynet::CONFIG[:SKYNET_PIDS_FILE] ||= File.expand_path("../log/skynet.pid")
20
+ Skynet::CONFIG[:SKYNET_LOG_FILE] ||= File.expand_path("../log/skynet.log")
21
+ <% end -%>
22
+
23
+ <% if mysql -%>
24
+ # Use the mysql message queue adapter
25
+ Skynet::CONFIG[:MESSAGE_QUEUE_ADAPTER] = "Skynet::MessageQueueAdapter::Mysql"
26
+ <% if not in_rails -%>
27
+ Skynet::CONFIG[:MYSQL_HOST] = "localhost"
28
+ Skynet::CONFIG[:MYSQL_USERNAME] = "root"
29
+ Skynet::CONFIG[:MYSQL_PASSWORD] = ""
30
+ Skynet::CONFIG[:MYSQL_DATABASE] = "skynet"
31
+ <% end -%>
32
+ <% end -%>
20
33
 
21
34
  begin
22
35
  mq = Skynet::MessageQueue.new
@@ -25,7 +38,7 @@ rescue Skynet::ConnectionError
25
38
  pid = fork do
26
39
  exec("skynet_tuplespace_server start")
27
40
  end
28
- sleep 3
41
+ sleep Skynet::CONFIG[:TS_SERVER_START_DELAY]
29
42
  end
30
43
  end
31
44