aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
authorJohn Hurliman2009-10-20 10:33:23 -0700
committerJohn Hurliman2009-10-20 10:33:23 -0700
commit9a5e7222cef7e81fee0c992c4557ac56e9665808 (patch)
tree2167b485454b513387fe239630038e83642613e6 /OpenSim/Region/CoreModules
parent* Optimized sending of terrain data (diff)
downloadopensim-SC_OLD-9a5e7222cef7e81fee0c992c4557ac56e9665808.zip
opensim-SC_OLD-9a5e7222cef7e81fee0c992c4557ac56e9665808.tar.gz
opensim-SC_OLD-9a5e7222cef7e81fee0c992c4557ac56e9665808.tar.bz2
opensim-SC_OLD-9a5e7222cef7e81fee0c992c4557ac56e9665808.tar.xz
* Removing cruft left over from the conversion to the new texture sending and UDP code
* Changing the cache modules to only initialize the caches if they are actually enabled. Should save a bit of resources from unused cache systems
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs302
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs87
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs265
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureSender/Tests/TextureSenderTests.cs180
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs212
-rw-r--r--OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs10
-rw-r--r--OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs7
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs51
-rw-r--r--OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs43
9 files changed, 45 insertions, 1112 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs b/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs
deleted file mode 100644
index 71ff28c..0000000
--- a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs
+++ /dev/null
@@ -1,302 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
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 OpenSimulator 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 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Threading;
32using log4net;
33using Nini.Config;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Framework.Communications.Cache;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using BlockingQueue = OpenSim.Framework.BlockingQueue<OpenSim.Region.Framework.Interfaces.ITextureSender>;
40using OpenSim.Services.Interfaces;
41
42namespace OpenSim.Region.CoreModules.Agent.TextureDownload
43{
44 public class TextureDownloadModule : IRegionModule
45 {
46 private static readonly ILog m_log
47 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 /// <summary>
50 /// There is one queue for all textures waiting to be sent, regardless of the requesting user.
51 /// </summary>
52 private readonly BlockingQueue m_queueSenders
53 = new BlockingQueue();
54
55 /// <summary>
56 /// Each user has their own texture download service.
57 /// </summary>
58 private readonly Dictionary<UUID, UserTextureDownloadService> m_userTextureServices =
59 new Dictionary<UUID, UserTextureDownloadService>();
60
61 private Scene m_scene;
62 private List<Scene> m_scenes = new List<Scene>();
63
64 public TextureDownloadModule()
65 {
66 }
67
68 #region IRegionModule Members
69
70 public void Initialise(Scene scene, IConfigSource config)
71 {
72
73 if (m_scene == null)
74 {
75 //m_log.Debug("Creating Texture download module");
76 m_scene = scene;
77 //m_thread = new Thread(new ThreadStart(ProcessTextureSenders));
78 //m_thread.Name = "ProcessTextureSenderThread";
79 //m_thread.IsBackground = true;
80 //m_thread.Start();
81 //ThreadTracker.Add(m_thread);
82 }
83
84 if (!m_scenes.Contains(scene))
85 {
86 m_scenes.Add(scene);
87 m_scene = scene;
88 m_scene.EventManager.OnNewClient += NewClient;
89 m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence;
90 }
91 }
92
93 public void PostInitialise()
94 {
95 }
96
97 public void Close()
98 {
99 }
100
101 public string Name
102 {
103 get { return "TextureDownloadModule"; }
104 }
105
106 public bool IsSharedModule
107 {
108 get { return false; }
109 }
110
111 #endregion
112
113 /// <summary>
114 /// Cleanup the texture service related objects for the removed presence.
115 /// </summary>
116 /// <param name="agentId"> </param>
117 private void EventManager_OnRemovePresence(UUID agentId)
118 {
119 UserTextureDownloadService textureService;
120
121 lock (m_userTextureServices)
122 {
123 if (m_userTextureServices.TryGetValue(agentId, out textureService))
124 {
125 textureService.Close();
126 //m_log.DebugFormat("[TEXTURE MODULE]: Removing UserTextureServices from {0}", m_scene.RegionInfo.RegionName);
127 m_userTextureServices.Remove(agentId);
128 }
129 }
130 }
131
132 public void NewClient(IClientAPI client)
133 {
134 UserTextureDownloadService textureService;
135
136 lock (m_userTextureServices)
137 {
138 if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
139 {
140 textureService.Close();
141 //m_log.DebugFormat("[TEXTURE MODULE]: Removing outdated UserTextureServices from {0}", m_scene.RegionInfo.RegionName);
142 m_userTextureServices.Remove(client.AgentId);
143 }
144 m_userTextureServices.Add(client.AgentId, new UserTextureDownloadService(client, m_scene, m_queueSenders));
145 }
146
147 client.OnRequestTexture += TextureRequest;
148 }
149
150 /// I'm commenting this out, and replacing it with the implementation below, which
151 /// may return a null value. This is necessary for avoiding race conditions
152 /// recreating UserTextureServices for clients that have just been closed.
153 /// That behavior of always returning a UserTextureServices was causing the
154 /// A-B-A problem (mantis #2855).
155 ///
156 ///// <summary>
157 ///// Does this user have a registered texture download service?
158 ///// </summary>
159 ///// <param name="userID"></param>
160 ///// <param name="textureService"></param>
161 ///// <returns>Always returns true, since a service is created if one does not already exist</returns>
162 //private bool TryGetUserTextureService(
163 // IClientAPI client, out UserTextureDownloadService textureService)
164 //{
165 // lock (m_userTextureServices)
166 // {
167 // if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
168 // {
169 // //m_log.DebugFormat("[TEXTURE MODULE]: Found existing UserTextureServices in ", m_scene.RegionInfo.RegionName);
170 // return true;
171 // }
172
173 // m_log.DebugFormat("[TEXTURE MODULE]: Creating new UserTextureServices in ", m_scene.RegionInfo.RegionName);
174 // textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders);
175 // m_userTextureServices.Add(client.AgentId, textureService);
176
177 // return true;
178 // }
179 //}
180
181 /// <summary>
182 /// Does this user have a registered texture download service?
183 /// </summary>
184 /// <param name="userID"></param>
185 /// <param name="textureService"></param>
186 /// <returns>A UserTextureDownloadService or null in the output parameter, and true or false accordingly.</returns>
187 private bool TryGetUserTextureService(IClientAPI client, out UserTextureDownloadService textureService)
188 {
189 lock (m_userTextureServices)
190 {
191 if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
192 {
193 //m_log.DebugFormat("[TEXTURE MODULE]: Found existing UserTextureServices in ", m_scene.RegionInfo.RegionName);
194 return true;
195 }
196
197 textureService = null;
198 return false;
199 }
200 }
201
202 /// <summary>
203 /// Start the process of requesting a given texture.
204 /// </summary>
205 /// <param name="sender"> </param>
206 /// <param name="e"></param>
207 public void TextureRequest(Object sender, TextureRequestArgs e)
208 {
209 IClientAPI client = (IClientAPI)sender;
210
211 if (e.Priority == 1016001f) // Preview
212 {
213 if (client.Scene is Scene)
214 {
215 Scene scene = (Scene)client.Scene;
216
217 CachedUserInfo profile = scene.CommsManager.UserProfileCacheService.GetUserDetails(client.AgentId);
218 if (profile == null) // Deny unknown user
219 return;
220
221 IInventoryService invService = scene.InventoryService;
222 if (invService.GetRootFolder(client.AgentId) == null) // Deny no inventory
223 return;
224
225 // Diva 2009-08-13: this test doesn't make any sense to many devs
226 //if (profile.UserProfile.GodLevel < 200 && profile.RootFolder.FindAsset(e.RequestedAssetID) == null) // Deny if not owned
227 //{
228 // m_log.WarnFormat("[TEXTURE]: user {0} doesn't have permissions to texture {1}");
229 // return;
230 //}
231
232 m_log.Debug("Texture preview");
233 }
234 }
235
236 UserTextureDownloadService textureService;
237
238 if (TryGetUserTextureService(client, out textureService))
239 {
240 textureService.HandleTextureRequest(e);
241 }
242 }
243
244 /// <summary>
245 /// Entry point for the thread dedicated to processing the texture queue.
246 /// </summary>
247 public void ProcessTextureSenders()
248 {
249 ITextureSender sender = null;
250
251 try
252 {
253 while (true)
254 {
255 sender = m_queueSenders.Dequeue();
256
257 if (sender.Cancel)
258 {
259 TextureSent(sender);
260
261 sender.Cancel = false;
262 }
263 else
264 {
265 bool finished = sender.SendTexturePacket();
266 if (finished)
267 {
268 TextureSent(sender);
269 }
270 else
271 {
272 m_queueSenders.Enqueue(sender);
273 }
274 }
275
276 // Make sure that any sender we currently have can get garbage collected
277 sender = null;
278
279 //m_log.InfoFormat("[TEXTURE] Texture sender queue size: {0}", m_queueSenders.Count());
280 }
281 }
282 catch (Exception e)
283 {
284 // TODO: Let users in the sim and those entering it and possibly an external watchdog know what has happened
285 m_log.ErrorFormat(
286 "[TEXTURE]: Texture send thread terminating with exception. PLEASE REBOOT YOUR SIM - TEXTURES WILL NOT BE AVAILABLE UNTIL YOU DO. Exception is {0}",
287 e);
288 }
289 }
290
291 /// <summary>
292 /// Called when the texture has finished sending.
293 /// </summary>
294 /// <param name="sender"></param>
295 private void TextureSent(ITextureSender sender)
296 {
297 sender.Sending = false;
298 //m_log.DebugFormat("[TEXTURE]: Removing download stat for {0}", sender.assetID);
299 m_scene.StatsReporter.AddPendingDownloads(-1);
300 }
301 }
302}
diff --git a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs b/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs
deleted file mode 100644
index ba735a7..0000000
--- a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs
+++ /dev/null
@@ -1,87 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
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 OpenSimulator 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 */
27
28using OpenMetaverse;
29using OpenSim.Framework;
30using OpenSim.Region.Framework.Interfaces;
31
32namespace OpenSim.Region.CoreModules.Agent.TextureDownload
33{
34 /// <summary>
35 /// Sends a 'texture not found' packet back to the client
36 /// </summary>
37 public class TextureNotFoundSender : ITextureSender
38 {
39 // private static readonly log4net.ILog m_log
40 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
41
42 // private IClientAPI m_client;
43 // private UUID m_textureId;
44
45 public TextureNotFoundSender(IClientAPI client, UUID textureID)
46 {
47 //m_client = client;
48 //m_textureId = textureID;
49 }
50
51 #region ITextureSender Members
52
53 public bool Sending
54 {
55 get { return false; }
56 set { }
57 }
58
59 public bool Cancel
60 {
61 get { return false; }
62 set { }
63 }
64
65 // See ITextureSender
66 public void UpdateRequest(int discardLevel, uint packetNumber)
67 {
68 // No need to implement since priority changes don't affect this operation
69 }
70
71 // See ITextureSender
72 public bool SendTexturePacket()
73 {
74 // m_log.DebugFormat(
75 // "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found",
76 // m_textureId);
77
78 // XXX Temporarily disabling as this appears to be causing client crashes on at least
79 // 1.19.0(5) of the Linden Second Life client.
80 // m_client.SendImageNotFound(m_textureId);
81
82 return true;
83 }
84
85 #endregion
86 }
87}
diff --git a/OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs b/OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs
deleted file mode 100644
index 19f0f90..0000000
--- a/OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs
+++ /dev/null
@@ -1,265 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
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 OpenSimulator 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 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications.Limit;
35using OpenSim.Framework.Statistics;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes;
38
39namespace OpenSim.Region.CoreModules.Agent.TextureDownload
40{
41 /// <summary>
42 /// This module sets up texture senders in response to client texture requests, and places them on a
43 /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the
44 /// asset cache).
45 /// </summary>
46 public class UserTextureDownloadService
47 {
48// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 /// <summary>
51 /// True if the service has been closed, probably because a user with texture requests still queued
52 /// logged out.
53 /// </summary>
54 private bool closed;
55
56 /// <summary>
57 /// We will allow the client to request the same texture n times before dropping further requests
58 ///
59 /// This number includes repeated requests for the same texture at different resolutions (which we don't
60 /// currently handle properly as far as I know). However, this situation should be handled in a more
61 /// sophisticated way.
62 /// </summary>
63// private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5;
64
65 /// <summary>
66 /// XXX Also going to limit requests for found textures.
67 /// </summary>
68// private readonly IRequestLimitStrategy<UUID> foundTextureLimitStrategy
69// = new RepeatLimitStrategy<UUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
70
71// private readonly IClientAPI m_client;
72 private readonly Scene m_scene;
73
74 /// <summary>
75 /// Texture Senders are placed in this queue once they have received their texture from the asset
76 /// cache. Another module actually invokes the send.
77 /// </summary>
78// private readonly OpenSim.Framework.BlockingQueue<ITextureSender> m_sharedSendersQueue;
79
80 /// <summary>
81 /// Holds texture senders before they have received the appropriate texture from the asset cache.
82 /// </summary>
83 private readonly Dictionary<UUID, TextureSender.TextureSender> m_textureSenders = new Dictionary<UUID, TextureSender.TextureSender>();
84
85 /// <summary>
86 /// We're going to limit requests for the same missing texture.
87 /// XXX This is really a temporary solution to deal with the situation where a client continually requests
88 /// the same missing textures
89 /// </summary>
90// private readonly IRequestLimitStrategy<UUID> missingTextureLimitStrategy
91// = new RepeatLimitStrategy<UUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
92
93 public UserTextureDownloadService(
94 IClientAPI client, Scene scene, OpenSim.Framework.BlockingQueue<ITextureSender> sharedQueue)
95 {
96// m_client = client;
97 m_scene = scene;
98// m_sharedSendersQueue = sharedQueue;
99 }
100
101 /// <summary>
102 /// Handle a texture request. This involves creating a texture sender and placing it on the
103 /// previously passed in shared queue.
104 /// </summary>
105 /// <param name="e"></param>
106 public void HandleTextureRequest(TextureRequestArgs e)
107 {
108
109 //TextureSender.TextureSender textureSender;
110
111 //TODO: should be working out the data size/ number of packets to be sent for each discard level
112 //if ((e.DiscardLevel >= 0) || (e.Priority != 0))
113 //{
114 //lock (m_textureSenders)
115 //{
116 //if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
117 //{
118 // If we've received new non UUID information for this request and it hasn't dispatched
119 // yet, then update the request accordingly.
120 // textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber);
121 //}
122 //else
123 //{
124 // m_log.DebugFormat("[TEXTURE]: Received a request for texture {0}", e.RequestedAssetID);
125
126 //if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
127 //{
128 // m_log.DebugFormat(
129 // "[TEXTURE]: Refusing request for {0} from client {1}",
130 // e.RequestedAssetID, m_client.AgentId);
131
132 //return;
133 //}
134 //else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
135 //{
136 // if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID))
137 // {
138 // if (StatsManager.SimExtraStats != null)
139 // StatsManager.SimExtraStats.AddBlockedMissingTextureRequest();
140
141 // Commenting out this message for now as it causes too much noise with other
142 // debug messages.
143 // m_log.DebugFormat(
144 // "[TEXTURE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests",
145 // e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS);
146 // }
147
148 // return;
149 //}
150
151 m_scene.StatsReporter.AddPendingDownloads(1);
152
153 //TextureSender.TextureSender requestHandler = new TextureSender.TextureSender(m_client, e.DiscardLevel, e.PacketNumber);
154 //m_textureSenders.Add(e.RequestedAssetID, null);
155
156 m_scene.AssetService.Get(e.RequestedAssetID.ToString(), this, TextureReceived);
157
158
159 }
160
161 protected void TextureReceived(string id, Object sender, AssetBase asset)
162 {
163 if (asset != null)
164 TextureCallback(asset.FullID, asset);
165 }
166
167 /// <summary>
168 /// The callback for the asset cache when a texture has been retrieved. This method queues the
169 /// texture sender for processing.
170 /// </summary>
171 /// <param name="textureID"></param>
172 /// <param name="texture"></param>
173 public void TextureCallback(UUID textureID, AssetBase texture)
174 {
175 //m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false));
176
177 // There may still be texture requests pending for a logged out client
178 if (closed)
179 return;
180
181 /*
182 lock (m_textureSenders)
183 {
184 TextureSender.TextureSender textureSender;
185 if (m_textureSenders.TryGetValue(textureID, out textureSender))
186 {
187 // XXX It may be perfectly valid for a texture to have no data... but if we pass
188 // this on to the TextureSender it will blow up, so just discard for now.
189 // Needs investigation.
190 if (texture == null || texture.Data == null)
191 {
192 if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID))
193 {
194 missingTextureLimitStrategy.MonitorRequests(textureID);
195
196 // m_log.DebugFormat(
197 // "[TEXTURE]: Queueing first TextureNotFoundSender for {0}, client {1}",
198 // textureID, m_client.AgentId);
199 }
200
201 ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID);
202 EnqueueTextureSender(textureNotFoundSender);
203 }
204 else
205 {
206 if (!textureSender.ImageLoaded)
207 {
208 textureSender.TextureReceived(texture);
209 EnqueueTextureSender(textureSender);
210
211 foundTextureLimitStrategy.MonitorRequests(textureID);
212 }
213 }
214
215 //m_log.InfoFormat("[TEXTURE] Removing texture sender with uuid {0}", textureID);
216 m_textureSenders.Remove(textureID);
217 //m_log.InfoFormat("[TEXTURE] Current texture senders in dictionary: {0}", m_textureSenders.Count);
218 }
219 else
220 {
221 m_log.WarnFormat(
222 "[TEXTURE]: Got a texture uuid {0} with no sender object to handle it, this shouldn't happen",
223 textureID);
224 }
225 }
226 */
227 }
228
229 /// <summary>
230 /// Place a ready texture sender on the processing queue.
231 /// </summary>
232 /// <param name="textureSender"></param>
233// private void EnqueueTextureSender(ITextureSender textureSender)
234// {
235// textureSender.Cancel = false;
236// textureSender.Sending = true;
237//
238// if (!m_sharedSendersQueue.Contains(textureSender))
239// {
240// m_sharedSendersQueue.Enqueue(textureSender);
241// }
242// }
243
244 /// <summary>
245 /// Close this module.
246 /// </summary>
247 internal void Close()
248 {
249 closed = true;
250
251 lock (m_textureSenders)
252 {
253 foreach (TextureSender.TextureSender textureSender in m_textureSenders.Values)
254 {
255 textureSender.Cancel = true;
256 }
257
258 m_textureSenders.Clear();
259 }
260
261 // XXX: It might be possible to also remove pending texture requests from the asset cache queues,
262 // though this might also be more trouble than it's worth.
263 }
264 }
265}
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/Tests/TextureSenderTests.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/Tests/TextureSenderTests.cs
deleted file mode 100644
index efa275c..0000000
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/Tests/TextureSenderTests.cs
+++ /dev/null
@@ -1,180 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
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 OpenSimulator 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 */
27
28using System;
29using NUnit.Framework;
30using NUnit.Framework.SyntaxHelpers;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Tests.Common;
34using OpenSim.Tests.Common.Mock;
35
36namespace OpenSim.Region.CoreModules.Agent.TextureSender
37{
38 [TestFixture]
39 public class UserTextureSenderTests
40 {
41 public UUID uuid1;
42 public UUID uuid2;
43 public UUID uuid3;
44 public UUID uuid4;
45 public int npackets, testsize;
46 public TestClient client;
47 public TextureSender ts;
48 public static Random random = new Random();
49
50 [TestFixtureSetUp]
51 public void Init()
52 {
53 AgentCircuitData agent = new AgentCircuitData();
54 agent.AgentID = UUID.Random();
55 agent.firstname = "testfirstname";
56 agent.lastname = "testlastname";
57 agent.SessionID = UUID.Zero;
58 agent.SecureSessionID = UUID.Zero;
59 agent.circuitcode = 123;
60 agent.BaseFolder = UUID.Zero;
61 agent.InventoryFolder = UUID.Zero;
62 agent.startpos = Vector3.Zero;
63 agent.CapsPath = "http://wibble.com";
64 client = new TestClient(agent, null);
65 ts = new TextureSender(client, 0, 0);
66 testsize = random.Next(5000,15000);
67 npackets = CalculateNumPackets(testsize);
68 uuid1 = UUID.Random();
69 uuid2 = UUID.Random();
70 uuid3 = UUID.Random();
71 uuid4 = UUID.Random();
72 }
73
74 /// <summary>
75 /// Test sending package
76 /// </summary>
77 [Test]
78 public void T010_SendPkg()
79 {
80 TestHelper.InMethod();
81 // Normal sending
82 AssetBase abase = new AssetBase(uuid1, "asset one");
83 byte[] abdata = new byte[testsize];
84 random.NextBytes(abdata);
85 abase.Data = abdata;
86 bool isdone = false;
87 ts.TextureReceived(abase);
88 for (int i = 0; i < npackets; i++) {
89 isdone = ts.SendTexturePacket();
90 }
91
92 Assert.That(isdone,Is.False);
93 isdone = ts.SendTexturePacket();
94 Assert.That(isdone,Is.True);
95 }
96
97 [Test]
98 public void T011_UpdateReq()
99 {
100 TestHelper.InMethod();
101 // Test packet number start
102 AssetBase abase = new AssetBase(uuid2, "asset two");
103 byte[] abdata = new byte[testsize];
104 random.NextBytes(abdata);
105 abase.Data = abdata;
106
107 bool isdone = false;
108 ts.TextureReceived(abase);
109 ts.UpdateRequest(0,3);
110
111 for (int i = 0; i < npackets-3; i++) {
112 isdone = ts.SendTexturePacket();
113 }
114
115 Assert.That(isdone,Is.False);
116 isdone = ts.SendTexturePacket();
117 Assert.That(isdone,Is.True);
118
119 // Test discard level
120 abase = new AssetBase(uuid3, "asset three");
121 abdata = new byte[testsize];
122 random.NextBytes(abdata);
123 abase.Data = abdata;
124 isdone = false;
125 ts.TextureReceived(abase);
126 ts.UpdateRequest(-1,0);
127
128 Assert.That(ts.SendTexturePacket(),Is.True);
129
130 abase = new AssetBase(uuid4, "asset four");
131 abdata = new byte[testsize];
132 random.NextBytes(abdata);
133 abase.Data = abdata;
134 isdone = false;
135 ts.TextureReceived(abase);
136 ts.UpdateRequest(0,5);
137
138 for (int i = 0; i < npackets-5; i++) {
139 isdone = ts.SendTexturePacket();
140 }
141 Assert.That(isdone,Is.False);
142 isdone = ts.SendTexturePacket();
143 Assert.That(isdone,Is.True);
144 }
145
146 [Test]
147 public void T999_FinishStatus()
148 {
149 TestHelper.InMethod();
150 // Of the 4 assets "sent", only 2 sent the first part.
151 Assert.That(client.sentdatapkt.Count,Is.EqualTo(2));
152
153 // Sum of all packets sent:
154 int totalpkts = (npackets) + (npackets - 2) + (npackets - 4);
155 Assert.That(client.sentpktpkt.Count,Is.EqualTo(totalpkts));
156 }
157
158 /// <summary>
159 /// Calculate the number of packets that will be required to send the texture loaded into this sender
160 /// This is actually the number of 1000 byte packets not including an initial 600 byte packet...
161 /// Borrowed from TextureSender.cs
162 /// </summary>
163 /// <param name="length"></param>
164 /// <returns></returns>
165 private int CalculateNumPackets(int length)
166 {
167 int numPackets = 0;
168
169 if (length > 600)
170 {
171 //over 600 bytes so split up file
172 int restData = (length - 600);
173 int restPackets = ((restData + 999) / 1000);
174 numPackets = restPackets;
175 }
176
177 return numPackets;
178 }
179 }
180}
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs
deleted file mode 100644
index 62c5a32..0000000
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs
+++ /dev/null
@@ -1,212 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
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 OpenSimulator 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 */
27
28using System;
29using System.Reflection;
30using log4net;
31using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces;
33
34namespace OpenSim.Region.CoreModules.Agent.TextureSender
35{
36 /// <summary>
37 /// A TextureSender handles the process of receiving a texture requested by the client from the
38 /// AssetCache, and then sending that texture back to the client.
39 /// </summary>
40 public class TextureSender : ITextureSender
41 {
42 private static readonly ILog m_log
43 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 /// <summary>
46 /// Records the number of times texture send has been called.
47 /// </summary>
48 public int counter = 0;
49
50 public bool ImageLoaded = false;
51
52 /// <summary>
53 /// Holds the texture asset to send.
54 /// </summary>
55 private AssetBase m_asset;
56
57 //public UUID assetID { get { return m_asset.FullID; } }
58
59 // private bool m_cancel = false;
60
61 // See ITextureSender
62
63 // private bool m_sending = false;
64
65 /// <summary>
66 /// This is actually the number of extra packets required to send the texture data! We always assume
67 /// at least one is required.
68 /// </summary>
69 private int NumPackets = 0;
70
71 /// <summary>
72 /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts
73 /// at the 600th byte (0th indexed).
74 /// </summary>
75 private int PacketCounter = 0;
76
77 private int RequestedDiscardLevel = -1;
78 private IClientAPI RequestUser;
79 private uint StartPacketNumber = 0;
80
81 public TextureSender(IClientAPI client, int discardLevel, uint packetNumber)
82 {
83 RequestUser = client;
84 RequestedDiscardLevel = discardLevel;
85 StartPacketNumber = packetNumber;
86 }
87
88 #region ITextureSender Members
89
90 public bool Cancel
91 {
92 get { return false; }
93 set
94 {
95 // m_cancel = value;
96 }
97 }
98
99 public bool Sending
100 {
101 get { return false; }
102 set
103 {
104 // m_sending = value;
105 }
106 }
107
108 // See ITextureSender
109 public void UpdateRequest(int discardLevel, uint packetNumber)
110 {
111 RequestedDiscardLevel = discardLevel;
112 StartPacketNumber = packetNumber;
113 PacketCounter = (int)StartPacketNumber;
114 }
115
116 // See ITextureSender
117 public bool SendTexturePacket()
118 {
119 //m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID);
120
121 SendPacket();
122 counter++;
123 if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) ||
124 ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets / (RequestedDiscardLevel + 1)))))
125 {
126 return true;
127 }
128 return false;
129 }
130
131 #endregion
132
133 /// <summary>
134 /// Load up the texture data to send.
135 /// </summary>
136 /// <param name="asset"></param>
137 public void TextureReceived(AssetBase asset)
138 {
139 m_asset = asset;
140 NumPackets = CalculateNumPackets(asset.Data.Length);
141 PacketCounter = (int)StartPacketNumber;
142 ImageLoaded = true;
143 }
144
145 /// <summary>
146 /// Sends a texture packet to the client.
147 /// </summary>
148 private void SendPacket()
149 {
150 if (PacketCounter <= NumPackets)
151 {
152 if (PacketCounter == 0)
153 {
154 if (NumPackets == 0)
155 {
156 RequestUser.SendImageFirstPart(1, m_asset.FullID, (uint)m_asset.Data.Length, m_asset.Data, 2);
157 PacketCounter++;
158 }
159 else
160 {
161 byte[] ImageData1 = new byte[600];
162 Array.Copy(m_asset.Data, 0, ImageData1, 0, 600);
163
164 RequestUser.SendImageFirstPart(
165 (ushort)(NumPackets), m_asset.FullID, (uint)m_asset.Data.Length, ImageData1, 2);
166 PacketCounter++;
167 }
168 }
169 else
170 {
171 int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1));
172 if (size > 1000) size = 1000;
173 byte[] imageData = new byte[size];
174 try
175 {
176 Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), imageData, 0, size);
177 }
178 catch (ArgumentOutOfRangeException)
179 {
180 m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" +
181 m_asset.ID);
182 return;
183 }
184
185 RequestUser.SendImageNextPart((ushort)PacketCounter, m_asset.FullID, imageData);
186 PacketCounter++;
187 }
188 }
189 }
190
191 /// <summary>
192 /// Calculate the number of packets that will be required to send the texture loaded into this sender
193 /// This is actually the number of 1000 byte packets not including an initial 600 byte packet...
194 /// </summary>
195 /// <param name="length"></param>
196 /// <returns></returns>
197 private int CalculateNumPackets(int length)
198 {
199 int numPackets = 0;
200
201 if (length > 600)
202 {
203 //over 600 bytes so split up file
204 int restData = (length - 600);
205 int restPackets = ((restData + 999) / 1000);
206 numPackets = restPackets;
207 }
208
209 return numPackets;
210 }
211 }
212}
diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
index 66ca7c2..1add0ab 100644
--- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
@@ -155,14 +155,6 @@ namespace OpenSim.Region.CoreModules.Asset
155 private int m_hitCount; 155 private int m_hitCount;
156 156
157 /// <summary> 157 /// <summary>
158 /// Initialize asset cache module with default parameters.
159 /// </summary>
160 public void Initialize()
161 {
162 Initialize(DefaultMaxSize, DefaultMaxCount, DefaultExpirationTime);
163 }
164
165 /// <summary>
166 /// Initialize asset cache module, with custom parameters. 158 /// Initialize asset cache module, with custom parameters.
167 /// </summary> 159 /// </summary>
168 /// <param name="maximalSize"> 160 /// <param name="maximalSize">
@@ -174,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Asset
174 /// <param name="expirationTime"> 166 /// <param name="expirationTime">
175 /// Asset's expiration time. 167 /// Asset's expiration time.
176 /// </param> 168 /// </param>
177 public void Initialize(long maximalSize, int maximalCount, TimeSpan expirationTime) 169 protected void Initialize(long maximalSize, int maximalCount, TimeSpan expirationTime)
178 { 170 {
179 if (maximalSize <= 0 || maximalCount <= 0) 171 if (maximalSize <= 0 || maximalCount <= 0)
180 { 172 {
diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
index 0a7e736..7da5e7a 100644
--- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
@@ -44,10 +44,8 @@ namespace OpenSim.Region.CoreModules.Asset
44 LogManager.GetLogger( 44 LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType); 45 MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 private bool m_Enabled = false; 47 private bool m_Enabled;
48 private Cache m_Cache = new Cache(CacheMedium.Memory, 48 private Cache m_Cache;
49 CacheStrategy.Aggressive,
50 CacheFlags.AllowUpdate);
51 49
52 public string Name 50 public string Name
53 { 51 {
@@ -77,6 +75,7 @@ namespace OpenSim.Region.CoreModules.Asset
77 return; 75 return;
78 } 76 }
79 77
78 m_Cache = new Cache(CacheMedium.Memory, CacheStrategy.Aggressive, CacheFlags.AllowUpdate);
80 m_Enabled = true; 79 m_Enabled = true;
81 80
82 m_log.Info("[ASSET CACHE]: Core asset cache enabled"); 81 m_log.Info("[ASSET CACHE]: Core asset cache enabled");
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index d45c35c..cbdca16 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -61,24 +61,23 @@ namespace Flotsam.RegionModules.AssetCache
61 LogManager.GetLogger( 61 LogManager.GetLogger(
62 MethodBase.GetCurrentMethod().DeclaringType); 62 MethodBase.GetCurrentMethod().DeclaringType);
63 63
64 private bool m_Enabled = false; 64 private bool m_Enabled;
65 65
66 private const string m_ModuleName = "FlotsamAssetCache"; 66 private const string m_ModuleName = "FlotsamAssetCache";
67 private const string m_DefaultCacheDirectory = m_ModuleName; 67 private const string m_DefaultCacheDirectory = m_ModuleName;
68 private string m_CacheDirectory = m_DefaultCacheDirectory; 68 private string m_CacheDirectory = m_DefaultCacheDirectory;
69 69
70 70 private readonly List<char> m_InvalidChars = new List<char>();
71 private List<char> m_InvalidChars = new List<char>();
72 71
73 private int m_LogLevel = 1; 72 private int m_LogLevel = 1;
74 private ulong m_HitRateDisplay = 1; // How often to display hit statistics, given in requests 73 private ulong m_HitRateDisplay = 1; // How often to display hit statistics, given in requests
75 74
76 private static ulong m_Requests = 0; 75 private static ulong m_Requests;
77 private static ulong m_RequestsForInprogress = 0; 76 private static ulong m_RequestsForInprogress;
78 private static ulong m_DiskHits = 0; 77 private static ulong m_DiskHits;
79 private static ulong m_MemoryHits = 0; 78 private static ulong m_MemoryHits;
80 private static double m_HitRateMemory = 0.0; 79 private static double m_HitRateMemory;
81 private static double m_HitRateFile = 0.0; 80 private static double m_HitRateFile;
82 81
83#if WAIT_ON_INPROGRESS_REQUESTS 82#if WAIT_ON_INPROGRESS_REQUESTS
84 private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); 83 private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>();
@@ -87,7 +86,7 @@ namespace Flotsam.RegionModules.AssetCache
87 private List<string> m_CurrentlyWriting = new List<string>(); 86 private List<string> m_CurrentlyWriting = new List<string>();
88#endif 87#endif
89 88
90 private ExpiringCache<string, AssetBase> m_MemoryCache = new ExpiringCache<string, AssetBase>(); 89 private ExpiringCache<string, AssetBase> m_MemoryCache;
91 private bool m_MemoryCacheEnabled = true; 90 private bool m_MemoryCacheEnabled = true;
92 91
93 // Expiration is expressed in hours. 92 // Expiration is expressed in hours.
@@ -101,12 +100,12 @@ namespace Flotsam.RegionModules.AssetCache
101 private static int m_CacheDirectoryTierLen = 3; 100 private static int m_CacheDirectoryTierLen = 3;
102 private static int m_CacheWarnAt = 30000; 101 private static int m_CacheWarnAt = 30000;
103 102
104 private System.Timers.Timer m_CachCleanTimer = new System.Timers.Timer(); 103 private System.Timers.Timer m_CacheCleanTimer;
105 104
106 private IAssetService m_AssetService = null; 105 private IAssetService m_AssetService;
107 private List<Scene> m_Scenes = new List<Scene>(); 106 private List<Scene> m_Scenes = new List<Scene>();
108 107
109 private bool m_DeepScanBeforePurge = false; 108 private bool m_DeepScanBeforePurge;
110 109
111 public FlotsamAssetCache() 110 public FlotsamAssetCache()
112 { 111 {
@@ -128,14 +127,15 @@ namespace Flotsam.RegionModules.AssetCache
128 { 127 {
129 IConfig moduleConfig = source.Configs["Modules"]; 128 IConfig moduleConfig = source.Configs["Modules"];
130 129
131
132 if (moduleConfig != null) 130 if (moduleConfig != null)
133 { 131 {
134 string name = moduleConfig.GetString("AssetCaching", ""); 132 string name = moduleConfig.GetString("AssetCaching", String.Empty);
135 133
136 if (name == Name) 134 if (name == Name)
137 { 135 {
136 m_MemoryCache = new ExpiringCache<string, AssetBase>();
138 m_Enabled = true; 137 m_Enabled = true;
138
139 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} enabled", this.Name); 139 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} enabled", this.Name);
140 140
141 IConfig assetConfig = source.Configs["AssetCache"]; 141 IConfig assetConfig = source.Configs["AssetCache"];
@@ -163,21 +163,11 @@ namespace Flotsam.RegionModules.AssetCache
163 m_FileExpirationCleanupTimer = TimeSpan.FromHours(assetConfig.GetDouble("FileCleanupTimer", m_DefaultFileExpiration)); 163 m_FileExpirationCleanupTimer = TimeSpan.FromHours(assetConfig.GetDouble("FileCleanupTimer", m_DefaultFileExpiration));
164 if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero)) 164 if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
165 { 165 {
166 m_CachCleanTimer.Interval = m_FileExpirationCleanupTimer.TotalMilliseconds; 166 m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds);
167 m_CachCleanTimer.AutoReset = true; 167 m_CacheCleanTimer.AutoReset = true;
168 m_CachCleanTimer.Elapsed += CleanupExpiredFiles; 168 m_CacheCleanTimer.Elapsed += CleanupExpiredFiles;
169 m_CachCleanTimer.Enabled = true; 169 lock (m_CacheCleanTimer)
170 lock (m_CachCleanTimer) 170 m_CacheCleanTimer.Start();
171 {
172 m_CachCleanTimer.Start();
173 }
174 }
175 else
176 {
177 lock (m_CachCleanTimer)
178 {
179 m_CachCleanTimer.Enabled = false;
180 }
181 } 171 }
182 172
183 m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", 1); 173 m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", 1);
@@ -208,7 +198,6 @@ namespace Flotsam.RegionModules.AssetCache
208 MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the file and/or memory cache", HandleConsoleCommand); 198 MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the file and/or memory cache", HandleConsoleCommand);
209 MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand); 199 MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
210 MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand); 200 MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
211
212 } 201 }
213 } 202 }
214 } 203 }
diff --git a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
index 4869f5d..1365e69 100644
--- a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
@@ -45,11 +45,13 @@ namespace OpenSim.Region.CoreModules.Asset
45 LogManager.GetLogger( 45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType); 46 MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 private bool m_Enabled = false; 48 private bool m_Enabled;
49 private ICache m_Cache = new GlynnTucker.Cache.SimpleMemoryCache(); 49 private ICache m_Cache;
50 private ulong m_Hits;
51 private ulong m_Requests;
50 52
51 // Instrumentation 53 // Instrumentation
52 private uint m_DebugRate = 0; 54 private uint m_DebugRate;
53 55
54 public Type ReplaceableInterface 56 public Type ReplaceableInterface
55 { 57 {
@@ -72,6 +74,7 @@ namespace OpenSim.Region.CoreModules.Asset
72 74
73 if (name == Name) 75 if (name == Name)
74 { 76 {
77 m_Cache = new GlynnTucker.Cache.SimpleMemoryCache();
75 m_Enabled = true; 78 m_Enabled = true;
76 79
77 m_log.Info("[ASSET CACHE]: GlynnTucker asset cache enabled"); 80 m_log.Info("[ASSET CACHE]: GlynnTucker asset cache enabled");
@@ -80,7 +83,6 @@ namespace OpenSim.Region.CoreModules.Asset
80 IConfig cacheConfig = source.Configs["AssetCache"]; 83 IConfig cacheConfig = source.Configs["AssetCache"];
81 if (cacheConfig != null) 84 if (cacheConfig != null)
82 m_DebugRate = (uint)cacheConfig.GetInt("DebugRate", 0); 85 m_DebugRate = (uint)cacheConfig.GetInt("DebugRate", 0);
83
84 } 86 }
85 } 87 }
86 } 88 }
@@ -117,24 +119,6 @@ namespace OpenSim.Region.CoreModules.Asset
117 m_Cache.AddOrUpdate(asset.ID, asset); 119 m_Cache.AddOrUpdate(asset.ID, asset);
118 } 120 }
119 121
120 private ulong m_Hits = 0;
121 private ulong m_Requests = 0;
122 private void Debug(Object asset)
123 {
124 // Temporary instrumentation to measure the hit/miss rate
125 if (m_DebugRate > 0)
126 {
127 m_Requests++;
128 if (asset != null)
129 m_Hits++;
130
131 if ((m_Requests % m_DebugRate) == 0)
132 m_log.DebugFormat("[ASSET CACHE]: Hit Rate {0} / {1} == {2}%", m_Hits, m_Requests, ((float)m_Hits / m_Requests) * 100);
133
134 }
135 // End instrumentation
136 }
137
138 public AssetBase Get(string id) 122 public AssetBase Get(string id)
139 { 123 {
140 Object asset = null; 124 Object asset = null;
@@ -156,5 +140,20 @@ namespace OpenSim.Region.CoreModules.Asset
156 { 140 {
157 m_Cache.Clear(); 141 m_Cache.Clear();
158 } 142 }
143
144 private void Debug(Object asset)
145 {
146 // Temporary instrumentation to measure the hit/miss rate
147 if (m_DebugRate > 0)
148 {
149 ++m_Requests;
150 if (asset != null)
151 ++m_Hits;
152
153 if ((m_Requests % m_DebugRate) == 0)
154 m_log.DebugFormat("[ASSET CACHE]: Hit Rate {0} / {1} == {2}%", m_Hits, m_Requests, ((float)m_Hits / (float)m_Requests) * 100.0f);
155 }
156 // End instrumentation
157 }
159 } 158 }
160} 159}