rhoconnect 3.3.6 → 3.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. data/CHANGELOG.md +40 -4
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +27 -25
  4. data/bench/benchapp/Gemfile +7 -27
  5. data/bench/benchapp/config.ru +9 -31
  6. data/bench/blobapp/Gemfile +7 -27
  7. data/bench/blobapp/config.ru +9 -29
  8. data/bench/lib/bench.rb +8 -1
  9. data/bench/lib/bench/test_data.rb +4 -1
  10. data/bench/scripts/blob_cud_script.rb +4 -0
  11. data/bench/scripts/cud_script.rb +7 -1
  12. data/bench/scripts/helpers.rb +1 -1
  13. data/bench/scripts/test_query_script.rb +20 -7
  14. data/bench/spec/bench_spec_helper.rb +3 -1
  15. data/bin/rhoconnect +22 -12
  16. data/commands/{commands/dtach_commands → dtach}/dtach_about.rb +0 -0
  17. data/commands/{commands/dtach_commands → dtach}/dtach_install.rb +0 -0
  18. data/commands/{commands/redis_commands → dtach}/redis_attach.rb +0 -0
  19. data/commands/execute.rb +14 -15
  20. data/commands/generators/update.rb +26 -0
  21. data/commands/{commands/redis_commands → redis}/redis_about.rb +0 -0
  22. data/commands/redis/redis_download.rb +13 -0
  23. data/commands/redis/redis_install.rb +26 -0
  24. data/commands/{commands/redis_commands → redis}/redis_make.rb +0 -0
  25. data/commands/{commands/redis_commands → redis}/redis_restart.rb +3 -2
  26. data/commands/{commands/redis_commands → redis}/redis_start.rb +0 -0
  27. data/commands/{commands/redis_commands → redis}/redis_startbg.rb +0 -0
  28. data/commands/{commands/redis_commands → redis}/redis_stop.rb +3 -2
  29. data/commands/{commands/rhoconnect → rhoconnect}/clean_start.rb +0 -0
  30. data/commands/{commands/rhoconnect → rhoconnect}/config.rb +7 -2
  31. data/commands/{commands/rhoconnect → rhoconnect}/create_user.rb +0 -0
  32. data/commands/{commands/rhoconnect → rhoconnect}/delete_device.rb +0 -0
  33. data/commands/{commands/rhoconnect → rhoconnect}/delete_user.rb +0 -0
  34. data/commands/{commands/rhoconnect → rhoconnect}/flushdb.rb +4 -4
  35. data/commands/{commands/rhoconnect → rhoconnect}/get_token.rb +0 -0
  36. data/commands/{commands/rhoconnect → rhoconnect}/reset.rb +0 -0
  37. data/commands/{commands/rhoconnect → rhoconnect}/reset_refresh.rb +0 -0
  38. data/commands/{commands/rhoconnect → rhoconnect}/restart.rb +0 -0
  39. data/commands/{commands/rhoconnect → rhoconnect}/secret.rb +0 -0
  40. data/commands/{commands/rhoconnect → rhoconnect}/set_admin_password.rb +0 -0
  41. data/commands/{commands/rhoconnect → rhoconnect}/spec.rb +0 -0
  42. data/commands/rhoconnect/start.rb +27 -0
  43. data/commands/{commands/rhoconnect → rhoconnect}/startbg.rb +0 -0
  44. data/commands/{commands/rhoconnect → rhoconnect}/startdebug.rb +2 -2
  45. data/commands/{commands/rhoconnect → rhoconnect}/stop.rb +3 -4
  46. data/commands/{commands/rhoconnect → rhoconnect}/version.rb +0 -0
  47. data/commands/{commands/rhoconnect → rhoconnect}/web.rb +0 -0
  48. data/commands/rhoconnect_attach/attach.rb +10 -0
  49. data/commands/rhoconnect_console/console.rb +16 -0
  50. data/commands/{commands/rhoconnect → rhoconnect_console}/console_helper.rb +0 -0
  51. data/commands/{commands/rhoconnect → rhoconnect_war}/war.rb +0 -0
  52. data/commands/{commands/redis_commands → utilities}/redis_runner.rb +22 -19
  53. data/commands/utilities/utilities.rb +6 -0
  54. data/doc/benchmarks.txt +2 -2
  55. data/doc/bulk-sync.txt +12 -1
  56. data/doc/client-java.txt +3 -3
  57. data/doc/client-objc.txt +1 -1
  58. data/doc/client.txt +5 -5
  59. data/doc/command-line.txt +80 -135
  60. data/doc/deploying.txt +119 -12
  61. data/doc/extending-rhoconnect-server.txt +1 -1
  62. data/doc/heroku-addon.txt +119 -23
  63. data/doc/install.txt +101 -39
  64. data/doc/java-plugin.txt +2 -2
  65. data/doc/licensing.txt +1 -1
  66. data/doc/plugin-intro.txt +3 -1
  67. data/doc/preparing-production.txt +4 -4
  68. data/doc/public/cli.txt +2 -2
  69. data/doc/push-backend-setup.txt +11 -1
  70. data/doc/push-client-setup.txt +72 -2
  71. data/doc/push-server-setup.txt +129 -8
  72. data/doc/rails-plugin.txt +245 -40
  73. data/doc/rest-api.txt +10 -6
  74. data/doc/rhoconnect-calculator.txt +237 -0
  75. data/doc/rhoconnect-redis-stack.txt +35 -0
  76. data/doc/session-and-configuration.txt +24 -0
  77. data/doc/settings.txt +51 -41
  78. data/doc/source-adapters.txt +45 -45
  79. data/doc/stats-middleware.txt +2 -2
  80. data/doc/supported-platforms.txt +6 -6
  81. data/doc/testing.txt +2 -2
  82. data/doc/tutorial.txt +63 -63
  83. data/examples/simple/Gemfile +7 -35
  84. data/examples/simple/config.ru +8 -26
  85. data/examples/simple/sources/product.rb +6 -6
  86. data/generators/rhoconnect.rb +5 -0
  87. data/generators/templates/application/Gemfile +7 -37
  88. data/generators/templates/application/Rakefile +8 -0
  89. data/generators/templates/application/config.ru +12 -31
  90. data/generators/templates/application/rcgemfile +44 -0
  91. data/generators/templates/application/settings/settings.yml +7 -5
  92. data/install.sh +4 -4
  93. data/installer/unix-like/create_texts.rb +7 -2
  94. data/installer/unix-like/rho_connect_install_constants.rb +2 -2
  95. data/installer/unix-like/rho_connect_install_installers.rb +1 -16
  96. data/lib/rhoconnect.rb +51 -38
  97. data/lib/rhoconnect/api/app/query.rb +4 -1
  98. data/lib/rhoconnect/api/app/search.rb +4 -1
  99. data/lib/rhoconnect/api/client/list_client_docs.rb +3 -1
  100. data/lib/rhoconnect/api/user/ping.rb +1 -5
  101. data/lib/rhoconnect/application/init.rb +43 -0
  102. data/lib/rhoconnect/async.rb +11 -6
  103. data/lib/rhoconnect/client_sync.rb +30 -37
  104. data/lib/rhoconnect/document.rb +4 -0
  105. data/lib/rhoconnect/graph_helper.rb +74 -56
  106. data/lib/rhoconnect/middleware/helpers.rb +4 -0
  107. data/lib/rhoconnect/ping.rb +1 -0
  108. data/lib/rhoconnect/ping/gcm.rb +58 -0
  109. data/lib/rhoconnect/predefined_adapters/bench_adapter.rb +7 -1
  110. data/lib/rhoconnect/source.rb +70 -56
  111. data/lib/rhoconnect/source_sync.rb +33 -5
  112. data/lib/rhoconnect/store.rb +358 -110
  113. data/lib/rhoconnect/user.rb +8 -0
  114. data/lib/rhoconnect/utilities.rb +16 -14
  115. data/lib/rhoconnect/version.rb +1 -1
  116. data/lib/rhoconnect/web-console/models/client.js +1 -1
  117. data/lib/rhoconnect/web-console/public/UNVR67bold.ttf +0 -0
  118. data/lib/rhoconnect/web-console/public/bootstrap.css +6 -0
  119. data/lib/rhoconnect/web-console/public/logo.png +0 -0
  120. data/lib/rhoconnect/web-console/server.rb +13 -11
  121. data/lib/rhoconnect/web-console/templates/index.erb +5 -5
  122. data/lib/rhoconnect/web-console/templates/jqplot.erb +1 -0
  123. data/lib/rhoconnect/web-console/views/doc.js +0 -4
  124. data/lib/rhoconnect/web-console/views/home.js +2 -1
  125. data/lib/rhoconnect/web-console/views/new_ping.js +11 -6
  126. data/lib/rhoconnect/web-console/views/stats.js +9 -5
  127. data/rhoconnect.gemspec +6 -4
  128. data/spec/api/app/fast_update_spec.rb +2 -2
  129. data/spec/api/source/get_source_params_spec.rb +1 -0
  130. data/spec/apps/rhotestapp/settings/settings.yml +5 -5
  131. data/spec/client_sync_spec.rb +3 -14
  132. data/spec/perf/perf_spec_helper.rb +11 -7
  133. data/spec/perf/store_perf_spec.rb +88 -11
  134. data/spec/ping/gcm_spec.rb +99 -0
  135. data/spec/server/server_spec.rb +7 -0
  136. data/spec/server/stats_spec.rb +9 -2
  137. data/spec/source_sync_spec.rb +29 -0
  138. data/spec/spec_helper.rb +40 -38
  139. data/spec/stats/record_spec.rb +18 -9
  140. data/spec/store_spec.rb +128 -19
  141. data/spec/testdata/10000-data.txt +0 -0
  142. data/spec/testdata/5-data.txt +0 -0
  143. data/spec/testdata/5000-data.txt +0 -0
  144. data/tasks/jasmine.rake +1 -0
  145. data/tasks/redis.rake +16 -13
  146. metadata +71 -39
  147. data/commands/commands/redis_commands/redis_download.rb +0 -33
  148. data/commands/commands/redis_commands/redis_install.rb +0 -26
  149. data/commands/commands/rhoconnect/attach.rb +0 -8
  150. data/commands/commands/rhoconnect/console.rb +0 -15
  151. data/commands/commands/rhoconnect/start.rb +0 -18
  152. data/commands/utilities/dtach_installed.rb +0 -10
data/doc/rest-api.txt CHANGED
@@ -97,24 +97,28 @@ Saves the url of the plugin's backend to the RhoConnect server.
97
97
  Retrieves stats for a given metric key:
98
98
 
99
99
  :::ruby
100
- RestClient.post(
100
+ RestClient.get(
101
101
  "#{server}/rc/v1/system/stats",
102
- {
103
- 'X-RhoConnect-API-TOKEN' => @api_token,
102
+ {
104
103
  :params => {:metric => 'foo',
105
104
  :start => 0,
106
105
  :finish => -1}
106
+ },
107
+ {
108
+ 'X-RhoConnect-API-TOKEN' => @api_token
107
109
  }
108
110
  )
109
111
 
110
112
  Retrieves a list of metric keys matching a given pattern. This supports 'glob' or '*' style pattern matching. For example, all metric keys associated with 'Product' source adapter methods:
111
113
 
112
114
  :::ruby
113
- RestClient.post(
115
+ RestClient.get(
114
116
  "#{server}/rc/v1/system/stats",
115
117
  {
116
- 'X-RhoConnect-API-TOKEN' => @api_token,
117
118
  :params => {:names => 'sources:*:Product'}
119
+ },
120
+ {
121
+ 'X-RhoConnect-API-TOKEN' => @api_token
118
122
  }
119
123
  )
120
124
 
@@ -490,7 +494,7 @@ Use this method only when you can ensure the integrity of the data.
490
494
  )
491
495
 
492
496
  #### `POST /app/v1/:source_name/fast_update`
493
- Push object updates to RhoConnect. This method doesn't involve pulling the existing data out of Redis. Instead it required user to provide the previous state of the data. This way, this method allows for very fast updates (since it just removes the previous data from set and adds new ones). However, no data integrity checks are performed. Therefore, this method must be used only if user can ensure the integrity of the data (i.e. previous state must exist, otherwise it won't be properly deleted). Also, this method can be used to perform fast appends and deletes for any of the object's attributes (However, you shoudn't use this method to remove all of the attributes, `fast_delete` should be used instead.)
497
+ Push object updates to RhoConnect. This method doesn't involve pulling the existing data out of Redis. Instead it required user to provide the previous state of the data. This way, this method allows for very fast updates (since it just removes the previous data from set and adds new ones). However, no data integrity checks are performed. Therefore, this method must be used only if user can ensure the integrity of the data (i.e. previous state must exist, otherwise it won't be properly deleted). Also, this method can be used to perform fast appends and deletes for any of the object's attributes (However, you shouldn't use this method to remove all of the attributes, `fast_delete` should be used instead.)
494
498
 
495
499
  **NOTE: you may use [ping](/rhoconnect/push) to notify client after the update and trigger sync.**
496
500
 
@@ -0,0 +1,237 @@
1
+ <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
2
+
3
+ <script type='text/javascript'>
4
+ $(function(){
5
+ var fileRef = document.createElement('script');
6
+ fileRef.setAttribute("type","text/javascript");
7
+ fileRef.setAttribute("src", "https://s3.amazonaws.com/rhoconnect-calc/raw_data.js");
8
+ document.body.appendChild(fileRef);
9
+ });
10
+
11
+ var totalAttrRange = new Array(5000,25000,50000,125000,250000,500000);
12
+ var totalSyncsRange = new Array(1000,10000,100000,500000,1000000,10000000);
13
+ var coefficient = 1.2;
14
+
15
+ $('#calc-submit').live('click',function(e){
16
+ e.preventDefault();
17
+ var numObj = $("#num_obj").val();
18
+ var numAttr = $("#num_attr").val();
19
+ var numDvces = $("#num_devices").val();
20
+ var avgResp = $("#avg_resp").val();
21
+ var syncFreq = $("#sync_freq").val();
22
+ var numObj = $("#num_obj").val();
23
+ var numUp = $("#num_up").val();
24
+ var res;
25
+ var cores;
26
+ var ram;
27
+ var key;
28
+
29
+ var total_attr = numObj * numAttr;
30
+ var total_syncs = numDvces * syncFreq;
31
+
32
+ key = get_boundary('totalAttrRange',total_attr) + ":" + get_boundary('totalSyncsRange',total_syncs) + ':0:0';
33
+ res = raw_data[key];
34
+ ram = (total_attr/10000) * numDvces * 1.2* 0.001;
35
+ ram = Math.round(ram * 100)/100;
36
+ ram += " GB";
37
+ if(res == undefined){
38
+ cores = "data not available";
39
+ result = ram + ",data not available";
40
+ }
41
+ else{
42
+ cores = res;
43
+ result = ram + ", " + cores;
44
+ }
45
+
46
+ $("td#cores")[0].innerHTML = cores;
47
+ $("td#ram")[0].innerHTML = ram;
48
+ $("#output").css("display","block");
49
+ $("#table-res").effect("highlight", {}, 1000);
50
+ $("input#entry_0").val(numObj);
51
+ $("input#entry_2").val(numAttr);
52
+ $("input#entry_3").val(numDvces);
53
+ $("input#entry_4").val(syncFreq);
54
+ $("input#entry_5").val(key);
55
+ $("input#entry_6").val(result);
56
+ $("input#entry_8").val(navigator.userAgent);
57
+ $.getJSON("http://h3manth.com/ip.php?callback=?",
58
+ function(data){
59
+ $("input#entry_7").val(data.ip);
60
+ $('#submitme')[0].click();
61
+ });
62
+ $.ajax({
63
+ url: "http://h3manth.com/ip.php?callback=?",
64
+ dataType: 'json',
65
+ success: function(data){
66
+ $("input#entry_7").val(data.ip);
67
+ $('#submitme')[0].click();
68
+ },
69
+ error: function(){
70
+ $("input#entry_7").val("error getting ip");
71
+ $('#submitme')[0].click();
72
+ }
73
+ });
74
+ });
75
+ function get_boundary(name,value){
76
+ var result = undefined;
77
+ value = parseInt(value);
78
+ arr = eval(name);
79
+
80
+ for(var i=0;i < arr.length;i++){
81
+ if(value < arr[i] * coefficient){
82
+ result = arr[i];
83
+ break;
84
+ }
85
+ }
86
+
87
+ return result;
88
+ }
89
+ </script>
90
+ RhoConnect Calculator
91
+ ==========
92
+ The RhoConnect Calculator helps you estimate the number of processor cores and redis server RAM required to deploy a RhoConnect Production environment.
93
+
94
+ 1 core equals 1 processor (at 2 GHz) running two thin processes.
95
+
96
+ <div id='output' class='pull-right' style='padding:25px 25px 0 0;display:none'>
97
+ Result:
98
+ <table id='table-res' class='table table=bordered'>
99
+ <tr>
100
+ <td>Number of Cores:</td><td id='cores'></td><td></td>
101
+ </tr>
102
+ <tr>
103
+ <td>Redis RAM:</td><td id='ram'></td><td id='ram_units'></td>
104
+ </tr>
105
+ </table>
106
+ </div>
107
+ <form id='calc-form' class='well form'>
108
+ <label>Number of Objects</label>
109
+ <input id='num_obj' type='number' class='input-xlarge' />
110
+ <label>Number of Attributes per Object</label>
111
+ <input id='num_attr' type='number' class='input-xlarge' />
112
+ <label>Number of Devices</label>
113
+ <input id='num_devices' type='number' class='input-xlarge' />
114
+ <label>Sync Frequency</label>
115
+ <div class='input-append'>
116
+ <input id='sync_freq' id='appendInput' type='number' class='span2' size='16'/>
117
+ <span class='add-on' style='margin-top:2px'>syncs per day</span>
118
+ </div>
119
+ <div style='display:none'>
120
+ <label>Your Average Web Service Response Time</label>
121
+ <input id='avg_resp' type='number' class='input-xlarge' value='0' disabled="disabled"/>
122
+ <label>Number of Updates per Day</label>
123
+ <input id='num_up' type='number' class='input-xlarge' disabled="disabled" value='0' /><br/>
124
+ </div>
125
+ <button id='calc-submit' type'submit' class='btn btn-primary'>Submit</button>
126
+ </form>
127
+
128
+ **NOTE: High Availability (HA) is not included into these numbers. So if your environment must provide HA, you will need to include enough extra storage and processor capacity in case of hardware failure.**
129
+
130
+ ### Calculator Fields
131
+ <ul>
132
+ <li><b>Number of Objects</b> - The number of objects across all of your models. If you have 10 models with 10 objects for each model, you would enter 100.</li>
133
+ <li><b>Number of Attributes per Object</b> - The average number of attributes per object. E.g. if you have 2 objects, 1 with 10 attributes and 1 with 12 attributes, you would enter 11.</li>
134
+ <li><b>Number of devices</b> - The total number of devices that will be using RhoConnect.</li>
135
+ <li><b>Sync Frequency</b> - The average sync frequency per device. E.g if you have 2 devices where one syncs 10 times per day and one sync 12 times per day, you would enter 11.</li>
136
+ </ul>
137
+
138
+ ### Result
139
+ <ul>
140
+ <li><b>Number of Cores</b> - The number of processor cores required (could be distributed across N number of servers).</li>
141
+ <li><b>Redis RAM</b> – RAM required for the master Redis instance. Currently only one master Redis instance can be defined. A typical deployment involves one master Redis instance (with no disk persistence) and N number of read-slaves (with persistence). Slave disk persistence would need at least 2X disk capacity where X is the master instance RAM requirement.</li>
142
+ </ul>
143
+
144
+
145
+
146
+ <script type="text/javascript">var submitted=false;</script>
147
+ <iframe name="hidden_iframe" id="hidden_iframe" style="display:none;" onload="if(submitted){}"></iframe>
148
+ <div style='display:none'>
149
+ <form id='gform' action="https://docs.google.com/a/rhomobile.com/spreadsheet/formResponse?formkey=dDBJeUVBQnNnTW1tWGZOSWNRbG84OFE6MQ&amp;ifq" method="post" target="hidden_iframe" onsubmit="submitted=true;" style='display:block'>
150
+ <br>
151
+ <div class="errorbox-good">
152
+ <div class="ss-item ss-text">
153
+ <div class="ss-form-entry">
154
+ <label class="ss-q-title" for="entry_0">Number of Objects</label>
155
+ <label class="ss-q-help" for="entry_0"></label>
156
+ <input type="text" name="entry.0.single" value="" class="ss-q-short" id="entry_0">
157
+ </div>
158
+ </div>
159
+ </div>
160
+ <br>
161
+ <div class="errorbox-good">
162
+ <div class="ss-item ss-text">
163
+ <div class="ss-form-entry">
164
+ <label class="ss-q-title" for="entry_2">Number of Attributes</label>
165
+ <label class="ss-q-help" for="entry_2"></label>
166
+ <input type="text" name="entry.2.single" value="" class="ss-q-short" id="entry_2">
167
+ </div>
168
+ </div>
169
+ </div>
170
+ <br>
171
+ <div class="errorbox-good">
172
+ <div class="ss-item ss-text">
173
+ <div class="ss-form-entry">
174
+ <label class="ss-q-title" for="entry_3">Number of Devices</label>
175
+ <label class="ss-q-help" for="entry_3"></label>
176
+ <input type="text" name="entry.3.single" value="" class="ss-q-short" id="entry_3">
177
+ </div>
178
+ </div>
179
+ </div>
180
+ <br>
181
+ <div class="errorbox-good">
182
+ <div class="ss-item ss-text">
183
+ <div class="ss-form-entry">
184
+ <label class="ss-q-title" for="entry_4">Sync Freq</label>
185
+ <label class="ss-q-help" for="entry_4"></label>
186
+ <input type="text" name="entry.4.single" value="" class="ss-q-short" id="entry_4">
187
+ </div>
188
+ </div>
189
+ </div>
190
+ <br>
191
+ <div class="errorbox-good">
192
+ <div class="ss-item ss-text">
193
+ <div class="ss-form-entry">
194
+ <label class="ss-q-title" for="entry_5">key</label>
195
+ <label class="ss-q-help" for="entry_5"></label>
196
+ <input type="text" name="entry.5.single" value="" class="ss-q-short" id="entry_5">
197
+ </div>
198
+ </div>
199
+ </div>
200
+ <br>
201
+ <div class="errorbox-good">
202
+ <div class="ss-item ss-text">
203
+ <div class="ss-form-entry">
204
+ <label class="ss-q-title" for="entry_6">value</label>
205
+ <label class="ss-q-help" for="entry_6"></label>
206
+ <input type="text" name="entry.6.single" value="" class="ss-q-short" id="entry_6">
207
+ </div>
208
+ </div>
209
+ </div>
210
+ <br>
211
+ <div class="errorbox-good">
212
+ <div class="ss-item ss-text">
213
+ <div class="ss-form-entry">
214
+ <label class="ss-q-title" for="entry_7">ip</label>
215
+ <label class="ss-q-help" for="entry_7"></label>
216
+ <input type="text" name="entry.7.single" value="" class="ss-q-short" id="entry_7">
217
+ </div>
218
+ </div>
219
+ </div>
220
+ <div class="errorbox-good">
221
+ <div class="ss-item ss-text">
222
+ <div class="ss-form-entry">
223
+ <label class="ss-q-title" for="entry_8">User Agent</label>
224
+ <label class="ss-q-help" for="entry_8"></label>
225
+ <input type="text" name="entry.8.single" value="" class="ss-q-short" id="entry_8">
226
+ </div>
227
+ </div>
228
+ </div>
229
+ <input type="hidden" name="pageNumber" value="0">
230
+ <input type="hidden" name="backupCache" value="">
231
+ <div class="ss-item ss-navigate">
232
+ <div class="ss-form-entry">
233
+ <input type="submit" name="submit" value="Submit" id='submitme'>
234
+ </div>
235
+ </div>
236
+ </form>
237
+ </div>
@@ -254,6 +254,41 @@ You are charged for the stack that you have created, by the hour. When you no lo
254
254
 
255
255
  <img src="http://rhodocs.s3.amazonaws.com/rhoconnect-redis-aws/delete-stack.png" alt="Delete Stack" />
256
256
 
257
+ ## High Availability/Failover for Redis server
258
+
259
+ The described architecture has a weak spot: a single point of failure (SPOF). If the Redis server is down or stops responding, then the entire Rhoconnect stack stops functioning. To address this issue, we need to implement failover — the continuation of a service after the failure of one or more of its components. Redis provides a very simple solution to
260
+ configure master-slave replication that allows slave Redis servers to be exact copies of master servers.
261
+ So if the master server goes down, we can issue a `SLAVEOF NO ONE` command to the slave and then switch RhoConnect apps to use the slave that is now the master.
262
+
263
+ The following is a one possible scenario of how it might be done on the Amazon cloud.
264
+
265
+ Redis High Availability proposal:
266
+
267
+ * RhoConnect applications do not send queries directly to the Redis server, but communicate with the Redis Elastic Load Balancer (RELB).
268
+ * RELB has 2 monitor servers, both running Haproxy and Monit services. RELB responsibility is to do a health check of monitor servers and to distribute incoming traffic to TCP proxy service.
269
+ * Each monitor machine has a TCP proxy which relays its traffic to the master redis server.
270
+ * Monit service role is to detect failure of redis servers and start recovery process.
271
+ * Monit checks redises on a regular basis. It runs a failover script `/home/ubuntu/failover` if there is an failure to get a valid response upon performing a PING command three times in a row.
272
+ * Failover script does automatic slave -> master promotion in the case of master failure, and reconfigures Haproxy service to relay traffic to the new master redis. It spins up a new Redis EC2 instance and sets it as slave on the new master.
273
+ * The failover script uses AWS `simpleBD` service to store current redis servers configuration (master/slave/backup). So,
274
+ if another instance of monitor server detects failure and calls the failover script, it will know the current status of the redis servers
275
+ and will wait until the recovery process that was initiated by another Monit service is over. Finally, the failover script reconfigures and restarts the Monit service to track a new pair of master/slave redis servers.
276
+ * 1 Redis master
277
+ * 1 Redis slave
278
+
279
+ The URL for the CloudFormation template that implements the described proposal is available here
280
+ [https://s3-us-west-1.amazonaws.com/rhoconnect-ca-deploy/rhoconnect-ha.txt](https://s3-us-west-1.amazonaws.com/rhoconnect-ca-deploy/rhoconnect-ha.txt)
281
+ and can be used for evaluation purposes.
282
+
283
+ The template will create a sample scalable rhoconnect stack with 2 elastic load balancers and 5 EC2 instances.
284
+
285
+ * RhoConnect Load Balancer
286
+ * 1 EC2 instance of RhoConnect application
287
+ * Redis Load Balancer
288
+ * 2 EC2 instances of monitor servers (Haproxy/Monit)
289
+ * 2 EC2 instances of redis servers (master/slave)
290
+
291
+
257
292
 
258
293
 
259
294
 
@@ -0,0 +1,24 @@
1
+ Session and configuration
2
+ ===
3
+
4
+ RhoConnect persists user session in a cookie which is handled by client executable. But some client may have an issue accessing a session cookie value due to platform security features involved.
5
+
6
+ At this moment well-known clients with such restrictions are Rhoconnect.js, Rhodes and ObjectiveC client on WinPhone7 platform.
7
+
8
+ To overcome cookie issue the *XDomainSessionWrapper* Rack middleware has been implemented and included to the RhoConnect distribution.
9
+ You can find it inside RhoConnect gem in *lib/rhoconnect/middleware/x_domain_session_wrapper.rb* file.
10
+
11
+ ## How to use
12
+
13
+ To use this workaround just put these lines in config.ru file right before *Rhoconnect::Server* settings:
14
+
15
+ :::ruby
16
+ require 'rhoconnect/x_domain_session_wrapper'
17
+ use XDomainSessionWrapper, \
18
+ :session_cookie => 'rhoconnect_session', \
19
+ :api_uri_regexp => /\A\/(api\/)?application/, \
20
+ :login_uri_regexp => /\A\/(api\/)?application\/clientlogin/
21
+
22
+ It just a sample, use real base URL values there. By default it configured just for URLs based on */api/application* pattern, not */application*.
23
+
24
+ **NOTE: Without mentioned configuration you may have login errors for Rhoconnect.js client and Rhodes application on WinPhone7 platform if your application points RhoConnect server as 'http://some-address.com/application'.
data/doc/settings.txt CHANGED
@@ -10,39 +10,45 @@ Application-wide settings are specified per deployment environment (`:test`, `:d
10
10
  Each of the environment categories must have the following entries:
11
11
 
12
12
  :::yaml
13
- :syncserver: <url> - application's base url
14
- :redis: <url> - Redis url
15
- :licensefile: <filename> - application's license file
16
-
17
- In addition, the following settings can be specified:
13
+ :syncserver: <url>
14
+ :redis: <url>
15
+ :licensefile: <filename>
16
+
17
+ `:syncserver`: application's base url.
18
+
19
+ `:redis`: Redis url.
20
+
21
+ `:licensefile`: application's license file.
22
+
23
+ In addition, you can specify the following settings:
18
24
 
19
25
  :::yaml
20
- :poll_interval_default: <secs> - default sync poll interval setting for source adapters.
21
- This setting is used as a default if source doesn't specify
22
- its own value. Also, it is applied to dynamic adapters
23
- as a default sync poll interval.
24
- :bulk_sync_poll_interval: <secs> - poll interval setting for bulk data sync
25
-
26
+ :connection_pool_size: <number_of_redis_connections>
27
+ :connection_pool_timeout: <secs>
28
+ :redis_timeout: <secs>
29
+ :poll_interval_default: <secs>
30
+ :bulk_sync_poll_interval: <secs>
26
31
  :c2dm_username: <google's email>
27
32
  :c2dm_passwd: <passwd>
28
- :authtoken: <authtoken> - these settings are used specifically for Android push notifications.
29
- In order to push messages to the Android device, your server needs to
30
- obtain Google's C2DM authentication token associated with the trusted google account.
31
- For this purpose, you can specify C2DM Google account's username/password combo
32
- via the `:c2dm_username` and `:c2dm_passwd` settings.
33
- At run-time, the system will use these credentials to obtain
34
- the C2DM token and store it in the Redis for the future use.
35
- Once the token is expired, the system will automatically
36
- connect to the Google C2DM service to renew the token.
37
-
38
- Alternatively, you can use `:authtoken` setting to specify
39
- the pre-defined authentication token. This token MUST be related to the role-based google account
40
- registered for your application. See [the rhodes push instructions](/rhodes/device-caps#push-notifications)
41
- for more details. To retrieve this token, use sample script [c2dm.rb](http://github.com/rhomobile/rhodes/blob/master/bin/c2dm.rb).
42
- Uncomment last two lines and put your google account specific data, then run it.
43
- It will print token to stdout.
44
- This approach, however, will not allow the server to connect
45
- to the C2DM service and renew the token once it is expired.
33
+ :authtoken: <authtoken>
34
+
35
+ `:connection_pool_size`: By default, RhoConnect maintains multiple concurrent connections to Redis organized in Connection Pool. This setting allows you to specify the size of the pool. By default, RhoConnect starts with five (5) Redis connections.
36
+
37
+ `:connection_pool_timeout`: The timeout value for the Redis Connection Pool, in seconds. Specifies how much time a request will wait for an available Redis connection. Default is 30 seconds.
38
+
39
+ `:redis_timeout:` - timeout setting for Redis commands. Default is 30 seconds.
40
+
41
+ `:poll_interval_default`: default sync poll interval setting for source adapters, in seconds. This setting is used as a default if source doesn't specify its own value. Also, it is applied to dynamic adapters as a default sync poll interval.
42
+
43
+ `:bulk_sync_poll_interval`: poll interval setting for bulk data sync, in seconds.
44
+
45
+ `:c2dm_username`: The email address for the C2DM Google account.
46
+
47
+ `:c2dm_passwd`: The password for the C2DM Google account.
48
+
49
+ `:authtoken`: these settings are used specifically for Android push notifications. In order to push messages to the Android device, your server needs to obtain Google's C2DM authentication token associated with the trusted google account. For this purpose, you can specify C2DM Google account's username/password combo via the `:c2dm_username` and `:c2dm_passwd` settings. At run-time, the system will use these credentials to obtain the C2DM token and store it in the Redis for the future use. Once the token is expired, the system will automatically connect to the Google C2DM service to renew the token.
50
+
51
+ Alternatively, you can use the `:authtoken` setting to specify the pre-defined authentication token. This token MUST be related to the role-based google account registered for your application. See [the rhodes push instructions](/rhodes/device-caps#push-notifications) for more details. To retrieve this token, use sample script [c2dm.rb](http://github.com/rhomobile/rhodes/blob/master/bin/c2dm.rb). Uncomment last two lines and put your google account specific data, then run it. It will print token to stdout. This approach, however, will not allow the server to connect to the C2DM service and renew the token once it is expired.
46
52
 
47
53
  ## Source settings
48
54
 
@@ -50,15 +56,19 @@ All source-specific settings are specified under the corresponding source name e
50
56
  Typical source settings include:
51
57
 
52
58
  :::yaml
53
- :poll_interval: <secs> - source's sync poll interval.
54
- :force_default: <true|false> - if specified, this setting forces to use
55
- default application poll interval
56
- even if source has its own setting.
57
- :partition_type: <app|user> - default partition type for the source
58
- :priority: <num> - these settings are used to determine the order the models
59
- are processed and synchronized. They might be useful when
60
- there are a set of linked together sources and client need
61
- to know in which order to process them.
62
- Priority starts from lower value 1. If priorities are not
63
- specified, then there are no guarantee that models will be
64
- listed and processed in natural order.
59
+ :poll_interval: <secs>
60
+ :force_default: <true|false>
61
+ :partition_type: <app|user>
62
+ :priority: <num>
63
+
64
+ `:poll_interval`: source's sync poll interval in seconds.
65
+
66
+ `:force_default`: true or false. If specified, this setting forces use of the default application poll interval even if source has its own setting.
67
+
68
+ `:partition_type`: app or user. default partition type for the source.
69
+
70
+ `:priority:` A priority number used to determine the order in which the models are processed and synchronized. This is useful when there are a set of linked together sources and the client needs to know in which order to process them. Priority starts from lower value 1. If priorities are not specified, then there is no guarantee that models will be listed and processed in natural order.
71
+
72
+
73
+
74
+