aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs')
-rw-r--r--OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs120
1 files changed, 102 insertions, 18 deletions
diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
index f1da4fa..565e4f2 100644
--- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
@@ -30,6 +30,7 @@ using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.IO; 31using System.IO;
32using System.Reflection; 32using System.Reflection;
33using System.Timers;
33using Nini.Config; 34using Nini.Config;
34using OpenSim.Framework; 35using OpenSim.Framework;
35using OpenSim.Framework.Console; 36using OpenSim.Framework.Console;
@@ -47,7 +48,9 @@ namespace OpenSim.Services.Connectors
47 48
48 private string m_ServerURI = String.Empty; 49 private string m_ServerURI = String.Empty;
49 private IImprovedAssetCache m_Cache = null; 50 private IImprovedAssetCache m_Cache = null;
50 51 private int m_retryCounter;
52 private Dictionary<int, List<AssetBase>> m_retryQueue = new Dictionary<int, List<AssetBase>>();
53 private Timer m_retryTimer;
51 public AssetServicesConnector() 54 public AssetServicesConnector()
52 { 55 {
53 } 56 }
@@ -84,6 +87,55 @@ namespace OpenSim.Services.Connectors
84 MainConsole.Instance.Commands.AddCommand("asset", false, "dump asset", 87 MainConsole.Instance.Commands.AddCommand("asset", false, "dump asset",
85 "dump asset <id> <file>", 88 "dump asset <id> <file>",
86 "dump one cached asset", HandleDumpAsset); 89 "dump one cached asset", HandleDumpAsset);
90
91 m_retryTimer = new Timer();
92 m_retryTimer.Elapsed += new ElapsedEventHandler(retryCheck);
93 m_retryTimer.Interval = 60000;
94 }
95
96 protected void retryCheck(object source, ElapsedEventArgs e)
97 {
98 m_retryCounter++;
99 if (m_retryCounter > 60) m_retryCounter -= 60;
100 List<int> keys = new List<int>();
101 foreach (int a in m_retryQueue.Keys)
102 {
103 keys.Add(a);
104 }
105 foreach (int a in keys)
106 {
107 //We exponentially fall back on frequency until we reach one attempt per hour
108 //The net result is that we end up in the queue for roughly 24 hours..
109 //24 hours worth of assets could be a lot, so the hope is that the region admin
110 //will have gotten the asset connector back online quickly!
111
112 int timefactor = a ^ 2;
113 if (timefactor > 60)
114 {
115 timefactor = 60;
116 }
117
118 //First, find out if we care about this timefactor
119 if (timefactor % a == 0)
120 {
121 //Yes, we do!
122 List<AssetBase> retrylist = m_retryQueue[a];
123 m_retryQueue.Remove(a);
124
125 foreach(AssetBase ass in retrylist)
126 {
127 Store(ass); //Store my ass. This function will put it back in the dictionary if it fails
128 }
129 }
130 }
131
132 if (m_retryQueue.Count == 0)
133 {
134 //It might only be one tick per minute, but I have
135 //repented and abandoned my wasteful ways
136 m_retryCounter = 0;
137 m_retryTimer.Stop();
138 }
87 } 139 }
88 140
89 protected void SetCache(IImprovedAssetCache cache) 141 protected void SetCache(IImprovedAssetCache cache)
@@ -98,8 +150,8 @@ namespace OpenSim.Services.Connectors
98 AssetBase asset = null; 150 AssetBase asset = null;
99 if (m_Cache != null) 151 if (m_Cache != null)
100 asset = m_Cache.Get(id); 152 asset = m_Cache.Get(id);
101 153
102 if (asset == null) 154 if (asset == null || asset.Data == null || asset.Data.Length == 0)
103 { 155 {
104 asset = SynchronousRestObjectRequester. 156 asset = SynchronousRestObjectRequester.
105 MakeRequest<int, AssetBase>("GET", uri, 0); 157 MakeRequest<int, AssetBase>("GET", uri, 0);
@@ -176,7 +228,7 @@ namespace OpenSim.Services.Connectors
176 if (m_Cache != null) 228 if (m_Cache != null)
177 asset = m_Cache.Get(id); 229 asset = m_Cache.Get(id);
178 230
179 if (asset == null) 231 if (asset == null || asset.Data == null || asset.Data.Length == 0)
180 { 232 {
181 bool result = false; 233 bool result = false;
182 234
@@ -203,11 +255,10 @@ namespace OpenSim.Services.Connectors
203 255
204 public string Store(AssetBase asset) 256 public string Store(AssetBase asset)
205 { 257 {
258 if (m_Cache != null)
259 m_Cache.Cache(asset);
206 if (asset.Temporary || asset.Local) 260 if (asset.Temporary || asset.Local)
207 { 261 {
208 if (m_Cache != null)
209 m_Cache.Cache(asset);
210
211 return asset.ID; 262 return asset.ID;
212 } 263 }
213 264
@@ -217,24 +268,57 @@ namespace OpenSim.Services.Connectors
217 try 268 try
218 { 269 {
219 newID = SynchronousRestObjectRequester. 270 newID = SynchronousRestObjectRequester.
220 MakeRequest<AssetBase, string>("POST", uri, asset); 271 MakeRequest<AssetBase, string>("POST", uri, asset, 25);
272 if (newID == null || newID == "")
273 {
274 newID = UUID.Zero.ToString();
275 }
221 } 276 }
222 catch (Exception e) 277 catch (Exception e)
223 { 278 {
224 m_log.WarnFormat("[ASSET CONNECTOR]: Unable to send asset {0} to asset server. Reason: {1}", asset.ID, e.Message); 279 newID = UUID.Zero.ToString();
225 } 280 }
226 281
227 if (newID != String.Empty) 282 if (newID == UUID.Zero.ToString())
228 { 283 {
229 // Placing this here, so that this work with old asset servers that don't send any reply back 284 //The asset upload failed, put it in a queue for later
230 // SynchronousRestObjectRequester returns somethins that is not an empty string 285 asset.UploadAttempts++;
231 if (newID != null) 286 if (asset.UploadAttempts > 30)
232 asset.ID = newID; 287 {
233 288 //By this stage we've been in the queue for a good few hours;
234 if (m_Cache != null) 289 //We're going to drop the asset.
235 m_Cache.Cache(asset); 290 m_log.ErrorFormat("[Assets] Dropping asset {0} - Upload has been in the queue for too long.", asset.ID.ToString());
291 }
292 else
293 {
294 if (!m_retryQueue.ContainsKey(asset.UploadAttempts))
295 {
296 m_retryQueue.Add(asset.UploadAttempts, new List<AssetBase>());
297 }
298 List<AssetBase> m_queue = m_retryQueue[asset.UploadAttempts];
299 m_queue.Add(asset);
300 m_log.WarnFormat("[Assets] Upload failed: {0} - Requeuing asset for another run.", asset.ID.ToString());
301 m_retryTimer.Start();
302 }
303 }
304 else
305 {
306 if (asset.UploadAttempts > 0)
307 {
308 m_log.InfoFormat("[Assets] Upload of {0} succeeded after {1} failed attempts", asset.ID.ToString(), asset.UploadAttempts.ToString());
309 }
310 if (newID != String.Empty)
311 {
312 // Placing this here, so that this work with old asset servers that don't send any reply back
313 // SynchronousRestObjectRequester returns somethins that is not an empty string
314 if (newID != null)
315 asset.ID = newID;
316
317 if (m_Cache != null)
318 m_Cache.Cache(asset);
319 }
236 } 320 }
237 return newID; 321 return asset.ID;
238 } 322 }
239 323
240 public bool UpdateContent(string id, byte[] data) 324 public bool UpdateContent(string id, byte[] data)