aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
diff options
context:
space:
mode:
authorMic Bowman2012-04-17 13:45:27 -0700
committerMic Bowman2012-04-17 13:45:27 -0700
commit5ff2bda587a50b73f470ba778348645953b6b4b0 (patch)
treeef2164de4447ca08b96f7e603b74763ea72ca2b0 /OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
parentmake the namespace for the ScriptModuleComms consistent with its file system ... (diff)
downloadopensim-SC_OLD-5ff2bda587a50b73f470ba778348645953b6b4b0.zip
opensim-SC_OLD-5ff2bda587a50b73f470ba778348645953b6b4b0.tar.gz
opensim-SC_OLD-5ff2bda587a50b73f470ba778348645953b6b4b0.tar.bz2
opensim-SC_OLD-5ff2bda587a50b73f470ba778348645953b6b4b0.tar.xz
This commit adds a new optional region module, JsonStore, that provides structured
storage (dictionaries and arrays of string values) for scripts and region modules. In addition, there are operations on the storage that enable "real" distributed computation between scripts through operations similar to those of a tuple space. Scripts can share task queues, implement shared locks or semaphores, etc. The structured store is limited to the current region and is not currently persisted. However, script operations are defined to initialize a store from a notecard and to serialize the store to a notecard. Documentation will be posted to the opensim wiki soon.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs429
1 files changed, 429 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
new file mode 100644
index 0000000..6dae956
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -0,0 +1,429 @@
1/*
2 * Copyright (c) Contributors
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using Mono.Addins;
28
29using System;
30using System.Reflection;
31using System.Threading;
32using System.Text;
33using System.Net;
34using System.Net.Sockets;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42using System.Collections.Generic;
43using System.Text.RegularExpressions;
44
45
46namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
47{
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreModule")]
49
50 public class JsonStoreModule : INonSharedRegionModule, IJsonStoreModule
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 private IConfig m_config = null;
56 private bool m_enabled = false;
57 private Scene m_scene = null;
58
59 private Dictionary<UUID,JsonStore> m_JsonValueStore;
60 private UUID m_sharedStore;
61
62#region IRegionModule Members
63
64 // -----------------------------------------------------------------
65 /// <summary>
66 /// Name of this shared module is it's class name
67 /// </summary>
68 // -----------------------------------------------------------------
69 public string Name
70 {
71 get { return this.GetType().Name; }
72 }
73
74 // -----------------------------------------------------------------
75 /// <summary>
76 /// Initialise this shared module
77 /// </summary>
78 /// <param name="scene">this region is getting initialised</param>
79 /// <param name="source">nini config, we are not using this</param>
80 // -----------------------------------------------------------------
81 public void Initialise(IConfigSource config)
82 {
83 try
84 {
85 if ((m_config = config.Configs["JsonStore"]) == null)
86 {
87 // There is no configuration, the module is disabled
88 m_log.InfoFormat("[JsonStore] no configuration info");
89 return;
90 }
91
92 m_enabled = m_config.GetBoolean("Enabled", m_enabled);
93 }
94 catch (Exception e)
95 {
96 m_log.ErrorFormat("[JsonStore] initialization error: {0}",e.Message);
97 return;
98 }
99
100 m_log.InfoFormat("[JsonStore] module {0} enabled",(m_enabled ? "is" : "is not"));
101 }
102
103 // -----------------------------------------------------------------
104 /// <summary>
105 /// everything is loaded, perform post load configuration
106 /// </summary>
107 // -----------------------------------------------------------------
108 public void PostInitialise()
109 {
110 }
111
112 // -----------------------------------------------------------------
113 /// <summary>
114 /// Nothing to do on close
115 /// </summary>
116 // -----------------------------------------------------------------
117 public void Close()
118 {
119 }
120
121 // -----------------------------------------------------------------
122 /// <summary>
123 /// </summary>
124 // -----------------------------------------------------------------
125 public void AddRegion(Scene scene)
126 {
127 if (m_enabled)
128 {
129 m_scene = scene;
130 m_scene.RegisterModuleInterface<IJsonStoreModule>(this);
131
132 m_sharedStore = UUID.Zero;
133 m_JsonValueStore = new Dictionary<UUID,JsonStore>();
134 m_JsonValueStore.Add(m_sharedStore,new JsonStore(""));
135 }
136 }
137
138 // -----------------------------------------------------------------
139 /// <summary>
140 /// </summary>
141 // -----------------------------------------------------------------
142 public void RemoveRegion(Scene scene)
143 {
144 // need to remove all references to the scene in the subscription
145 // list to enable full garbage collection of the scene object
146 }
147
148 // -----------------------------------------------------------------
149 /// <summary>
150 /// Called when all modules have been added for a region. This is
151 /// where we hook up events
152 /// </summary>
153 // -----------------------------------------------------------------
154 public void RegionLoaded(Scene scene)
155 {
156 if (m_enabled) {}
157 }
158
159 /// -----------------------------------------------------------------
160 /// <summary>
161 /// </summary>
162 // -----------------------------------------------------------------
163 public Type ReplaceableInterface
164 {
165 get { return null; }
166 }
167
168#endregion
169
170#region ScriptInvocationInteface
171
172 // -----------------------------------------------------------------
173 /// <summary>
174 ///
175 /// </summary>
176 // -----------------------------------------------------------------
177 public bool CreateStore(string value, out UUID result)
178 {
179 result = UUID.Zero;
180
181 if (! m_enabled) return false;
182
183 UUID uuid = UUID.Random();
184 JsonStore map = null;
185
186 try
187 {
188 map = new JsonStore(value);
189 }
190 catch (Exception e)
191 {
192 m_log.InfoFormat("[JsonStore] Unable to initialize store from {0}; {1}",value,e.Message);
193 return false;
194 }
195
196 lock (m_JsonValueStore)
197 m_JsonValueStore.Add(uuid,map);
198
199 result = uuid;
200 return true;
201 }
202
203 // -----------------------------------------------------------------
204 /// <summary>
205 ///
206 /// </summary>
207 // -----------------------------------------------------------------
208 public bool DestroyStore(UUID storeID)
209 {
210 if (! m_enabled) return false;
211
212 lock (m_JsonValueStore)
213 m_JsonValueStore.Remove(storeID);
214
215 return true;
216 }
217
218 // -----------------------------------------------------------------
219 /// <summary>
220 ///
221 /// </summary>
222 // -----------------------------------------------------------------
223 public bool TestPath(UUID storeID, string path, bool useJson)
224 {
225 if (! m_enabled) return false;
226
227 JsonStore map = null;
228 lock (m_JsonValueStore)
229 {
230 if (! m_JsonValueStore.TryGetValue(storeID,out map))
231 {
232 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
233 return true;
234 }
235 }
236
237 try
238 {
239 lock (map)
240 return map.TestPath(path,useJson);
241 }
242 catch (Exception e)
243 {
244 m_log.InfoFormat("[JsonStore] Path test failed for {0} in {1}; {2}",path,storeID,e.Message);
245 }
246
247 return false;
248 }
249
250 // -----------------------------------------------------------------
251 /// <summary>
252 ///
253 /// </summary>
254 // -----------------------------------------------------------------
255 public bool SetValue(UUID storeID, string path, string value, bool useJson)
256 {
257 if (! m_enabled) return false;
258
259 JsonStore map = null;
260 lock (m_JsonValueStore)
261 {
262 if (! m_JsonValueStore.TryGetValue(storeID,out map))
263 {
264 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
265 return false;
266 }
267 }
268
269 try
270 {
271 lock (map)
272 if (map.SetValue(path,value,useJson))
273 return true;
274 }
275 catch (Exception e)
276 {
277 m_log.InfoFormat("[JsonStore] Unable to assign {0} to {1} in {2}; {3}",value,path,storeID,e.Message);
278 }
279
280 return false;
281 }
282
283 // -----------------------------------------------------------------
284 /// <summary>
285 ///
286 /// </summary>
287 // -----------------------------------------------------------------
288 public bool RemoveValue(UUID storeID, string path)
289 {
290 if (! m_enabled) return false;
291
292 JsonStore map = null;
293 lock (m_JsonValueStore)
294 {
295 if (! m_JsonValueStore.TryGetValue(storeID,out map))
296 {
297 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
298 return false;
299 }
300 }
301
302 try
303 {
304 lock (map)
305 if (map.RemoveValue(path))
306 return true;
307 }
308 catch (Exception e)
309 {
310 m_log.InfoFormat("[JsonStore] Unable to remove {0} in {1}; {2}",path,storeID,e.Message);
311 }
312
313 return false;
314 }
315
316 // -----------------------------------------------------------------
317 /// <summary>
318 ///
319 /// </summary>
320 // -----------------------------------------------------------------
321 public bool GetValue(UUID storeID, string path, bool useJson, out string value)
322 {
323 value = String.Empty;
324
325 if (! m_enabled) return false;
326
327 JsonStore map = null;
328 lock (m_JsonValueStore)
329 {
330 if (! m_JsonValueStore.TryGetValue(storeID,out map))
331 return false;
332 }
333
334 try
335 {
336 lock (map)
337 {
338 return map.GetValue(path, out value, useJson);
339 }
340 }
341 catch (Exception e)
342 {
343 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.Message);
344 }
345
346 return false;
347 }
348
349 // -----------------------------------------------------------------
350 /// <summary>
351 ///
352 /// </summary>
353 // -----------------------------------------------------------------
354 public void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
355 {
356 if (! m_enabled)
357 {
358 cback(String.Empty);
359 return;
360 }
361
362 JsonStore map = null;
363 lock (m_JsonValueStore)
364 {
365 if (! m_JsonValueStore.TryGetValue(storeID,out map))
366 {
367 cback(String.Empty);
368 return;
369 }
370 }
371
372 try
373 {
374 lock (map)
375 {
376 map.TakeValue(path, useJson, cback);
377 return;
378 }
379 }
380 catch (Exception e)
381 {
382 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString());
383 }
384
385 cback(String.Empty);
386 }
387
388 // -----------------------------------------------------------------
389 /// <summary>
390 ///
391 /// </summary>
392 // -----------------------------------------------------------------
393 public void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
394 {
395 if (! m_enabled)
396 {
397 cback(String.Empty);
398 return;
399 }
400
401 JsonStore map = null;
402 lock (m_JsonValueStore)
403 {
404 if (! m_JsonValueStore.TryGetValue(storeID,out map))
405 {
406 cback(String.Empty);
407 return;
408 }
409 }
410
411 try
412 {
413 lock (map)
414 {
415 map.ReadValue(path, useJson, cback);
416 return;
417 }
418 }
419 catch (Exception e)
420 {
421 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString());
422 }
423
424 cback(String.Empty);
425 }
426
427#endregion
428 }
429}