aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment')
-rw-r--r--OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs90
1 files changed, 30 insertions, 60 deletions
diff --git a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs b/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs
index 4fdec65..a688cc8 100644
--- a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs
+++ b/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs
@@ -32,6 +32,7 @@ using libsecondlife;
32using libsecondlife.Packets; 32using libsecondlife.Packets;
33 33
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications.Limit;
35using OpenSim.Framework.Console; 36using OpenSim.Framework.Console;
36using OpenSim.Region.Environment.Interfaces; 37using OpenSim.Region.Environment.Interfaces;
37using OpenSim.Region.Environment.Scenes; 38using OpenSim.Region.Environment.Scenes;
@@ -54,27 +55,29 @@ namespace OpenSim.Region.Environment.Modules
54 private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5; 55 private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5;
55 56
56 /// <summary> 57 /// <summary>
57 /// Holds texture senders before they have received the appropriate texture from the asset cache. 58 /// We're going to limit repeated requests for the same missing texture.
58 /// </summary> 59 /// XXX This is really a temporary solution to deal with the situation where a client continually requests
59 private readonly Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>(); 60 /// the same missing textures
61 /// </summary>
62 private readonly IRequestLimitStrategy<LLUUID> missingTextureLimitStrategy
63 = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
60 64
61 /// <summary> 65 /// <summary>
62 /// Texture Senders are placed in this queue once they have received their texture from the asset 66 /// XXX Also going to limit repeated requests for found textures.
63 /// cache. Another module actually invokes the send.
64 /// </summary> 67 /// </summary>
65 private readonly BlockingQueue<ITextureSender> m_sharedSendersQueue; 68 private readonly IRequestLimitStrategy<LLUUID> foundTextureLimitStrategy
69 = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
66 70
67 /// <summary> 71 /// <summary>
68 /// We're going to record when we get a request for a particular missing texture for each client 72 /// Holds texture senders before they have received the appropriate texture from the asset cache.
69 /// XXX This is really a temporary solution to deal with the situation where a client continually requests
70 /// the same missing textures
71 /// </summary> 73 /// </summary>
72 private readonly Dictionary<LLUUID, int> missingTextureRequestCounts = new Dictionary<LLUUID, int>(); 74 private readonly Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>();
73 75
74 /// <summary> 76 /// <summary>
75 /// XXX Also going to record all the textures found and dispatched 77 /// Texture Senders are placed in this queue once they have received their texture from the asset
78 /// cache. Another module actually invokes the send.
76 /// </summary> 79 /// </summary>
77 private readonly Dictionary<LLUUID, int> dispatchedTextureRequestCounts = new Dictionary<LLUUID, int>(); 80 private readonly BlockingQueue<ITextureSender> m_sharedSendersQueue;
78 81
79 private readonly Scene m_scene; 82 private readonly Scene m_scene;
80 83
@@ -109,50 +112,21 @@ namespace OpenSim.Region.Environment.Modules
109 textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber); 112 textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber);
110 } 113 }
111 else 114 else
112 { 115 {
113 // If we've already told the client we're missing the texture, then don't ask the 116 if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
114 // asset server for it again - record the fact that it's missing instead.
115 // XXX This is to reduce (but not resolve) a current problem where some clients keep
116 // requesting the same textures
117 if (missingTextureRequestCounts.ContainsKey(e.RequestedAssetID))
118 { 117 {
119 missingTextureRequestCounts[e.RequestedAssetID] += 1; 118 return;
120
121 if (missingTextureRequestCounts[e.RequestedAssetID] > MAX_ALLOWED_TEXTURE_REQUESTS)
122 {
123 if (MAX_ALLOWED_TEXTURE_REQUESTS + 1 == missingTextureRequestCounts[e.RequestedAssetID])
124 {
125 m_log.DebugFormat(
126 "[USER TEXTURE DOWNLOAD SERVICE]: Dropping requests for notified missing texture {0} for {1} since we have received more than {2} requests",
127 e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS);
128 }
129
130 return;
131 }
132 } 119 }
133 else 120 else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
134 { 121 {
135 // If we keep receiving requests for textures we've already served to the client, 122 if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID))
136 // then stop sending them. This is a short term approach approach to the problem
137 // of clients which keep requesting the same texture - the long term approach
138 // will be to treat the cause (and possibly more generally cap the request
139 // queues as well/instead)
140 if (dispatchedTextureRequestCounts.ContainsKey(e.RequestedAssetID))
141 { 123 {
142 dispatchedTextureRequestCounts[e.RequestedAssetID] += 1; 124 m_log.DebugFormat(
143 125 "[USER TEXTURE DOWNLOAD SERVICE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {1} requests",
144 if (dispatchedTextureRequestCounts[e.RequestedAssetID] > MAX_ALLOWED_TEXTURE_REQUESTS) 126 e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS);
145 { 127 }
146// if (MAX_ALLOWED_TEXTURE_REQUESTS + 1 == dispatchedTextureRequestCounts[e.RequestedAssetID]) 128
147// { 129 return;
148// m_log.DebugFormat(
149// "[USER TEXTURE DOWNLOAD SERVICE]: Dropping further requests for dispatched/queued texture {0} for {1} since we have received more than {2} requests",
150// e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS);
151// }
152
153 return;
154 }
155 }
156 } 130 }
157 131
158 m_scene.AddPendingDownloads(1); 132 m_scene.AddPendingDownloads(1);
@@ -197,9 +171,9 @@ namespace OpenSim.Region.Environment.Modules
197 // Needs investigation. 171 // Needs investigation.
198 if (texture == null || texture.Data == null) 172 if (texture == null || texture.Data == null)
199 { 173 {
200 if (!missingTextureRequestCounts.ContainsKey(textureID)) 174 if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID))
201 { 175 {
202 missingTextureRequestCounts.Add(textureID, 1); 176 missingTextureLimitStrategy.MonitorRequests(textureID);
203 177
204 m_log.DebugFormat( 178 m_log.DebugFormat(
205 "[USER TEXTURE DOWNLOAD SERVICE]: Queueing first TextureNotFoundSender for {0}, client {1}", 179 "[USER TEXTURE DOWNLOAD SERVICE]: Queueing first TextureNotFoundSender for {0}, client {1}",
@@ -216,11 +190,7 @@ namespace OpenSim.Region.Environment.Modules
216 textureSender.TextureReceived(texture); 190 textureSender.TextureReceived(texture);
217 EnqueueTextureSender(textureSender); 191 EnqueueTextureSender(textureSender);
218 192
219 // Record the fact that we've put this texture in for dispatch 193 foundTextureLimitStrategy.MonitorRequests(textureID);
220 if (!dispatchedTextureRequestCounts.ContainsKey(textureID))
221 {
222 dispatchedTextureRequestCounts.Add(textureID, 1);
223 }
224 } 194 }
225 } 195 }
226 196