aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Data/AssetDataBase.cs2
-rw-r--r--OpenSim/Data/IAssetData.cs2
-rw-r--r--OpenSim/Data/MSSQL/MSSQLAssetData.cs4
-rw-r--r--OpenSim/Data/MySQL/MySQLAssetData.cs4
-rw-r--r--OpenSim/Data/SQLite/SQLiteAssetData.cs4
-rw-r--r--OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs4
-rw-r--r--OpenSim/Framework/AssetBase.cs8
-rw-r--r--OpenSim/Services/AssetService/AssetService.cs5
-rw-r--r--OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs99
-rw-r--r--OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs3
10 files changed, 116 insertions, 19 deletions
diff --git a/OpenSim/Data/AssetDataBase.cs b/OpenSim/Data/AssetDataBase.cs
index e1a810c..b4ae913 100644
--- a/OpenSim/Data/AssetDataBase.cs
+++ b/OpenSim/Data/AssetDataBase.cs
@@ -38,7 +38,7 @@ namespace OpenSim.Data
38 { 38 {
39 public abstract AssetBase GetAsset(UUID uuid); 39 public abstract AssetBase GetAsset(UUID uuid);
40 40
41 public abstract void StoreAsset(AssetBase asset); 41 public abstract bool StoreAsset(AssetBase asset);
42 public abstract bool ExistsAsset(UUID uuid); 42 public abstract bool ExistsAsset(UUID uuid);
43 43
44 public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count); 44 public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
diff --git a/OpenSim/Data/IAssetData.cs b/OpenSim/Data/IAssetData.cs
index 90d5eeb..065d3a5 100644
--- a/OpenSim/Data/IAssetData.cs
+++ b/OpenSim/Data/IAssetData.cs
@@ -34,7 +34,7 @@ namespace OpenSim.Data
34 public interface IAssetDataPlugin : IPlugin 34 public interface IAssetDataPlugin : IPlugin
35 { 35 {
36 AssetBase GetAsset(UUID uuid); 36 AssetBase GetAsset(UUID uuid);
37 void StoreAsset(AssetBase asset); 37 bool StoreAsset(AssetBase asset);
38 bool ExistsAsset(UUID uuid); 38 bool ExistsAsset(UUID uuid);
39 List<AssetMetadata> FetchAssetMetadataSet(int start, int count); 39 List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
40 void Initialise(string connect); 40 void Initialise(string connect);
diff --git a/OpenSim/Data/MSSQL/MSSQLAssetData.cs b/OpenSim/Data/MSSQL/MSSQLAssetData.cs
index c7488d8..c882555 100644
--- a/OpenSim/Data/MSSQL/MSSQLAssetData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLAssetData.cs
@@ -143,7 +143,7 @@ namespace OpenSim.Data.MSSQL
143 /// Create asset in m_database 143 /// Create asset in m_database
144 /// </summary> 144 /// </summary>
145 /// <param name="asset">the asset</param> 145 /// <param name="asset">the asset</param>
146 override public void StoreAsset(AssetBase asset) 146 override public bool StoreAsset(AssetBase asset)
147 { 147 {
148 148
149 string sql = 149 string sql =
@@ -192,10 +192,12 @@ namespace OpenSim.Data.MSSQL
192 try 192 try
193 { 193 {
194 command.ExecuteNonQuery(); 194 command.ExecuteNonQuery();
195 return true;
195 } 196 }
196 catch(Exception e) 197 catch(Exception e)
197 { 198 {
198 m_log.Error("[ASSET DB]: Error storing item :" + e.Message); 199 m_log.Error("[ASSET DB]: Error storing item :" + e.Message);
200 return false;
199 } 201 }
200 } 202 }
201 } 203 }
diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs
index fe5152a..f9ce3d9 100644
--- a/OpenSim/Data/MySQL/MySQLAssetData.cs
+++ b/OpenSim/Data/MySQL/MySQLAssetData.cs
@@ -153,7 +153,7 @@ namespace OpenSim.Data.MySQL
153 /// </summary> 153 /// </summary>
154 /// <param name="asset">Asset UUID to create</param> 154 /// <param name="asset">Asset UUID to create</param>
155 /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks> 155 /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
156 override public void StoreAsset(AssetBase asset) 156 override public bool StoreAsset(AssetBase asset)
157 { 157 {
158 lock (m_dbLock) 158 lock (m_dbLock)
159 { 159 {
@@ -201,12 +201,14 @@ namespace OpenSim.Data.MySQL
201 cmd.Parameters.AddWithValue("?data", asset.Data); 201 cmd.Parameters.AddWithValue("?data", asset.Data);
202 cmd.ExecuteNonQuery(); 202 cmd.ExecuteNonQuery();
203 cmd.Dispose(); 203 cmd.Dispose();
204 return true;
204 } 205 }
205 } 206 }
206 catch (Exception e) 207 catch (Exception e)
207 { 208 {
208 m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}", 209 m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
209 asset.FullID, asset.Name, e.Message); 210 asset.FullID, asset.Name, e.Message);
211 return false;
210 } 212 }
211 } 213 }
212 } 214 }
diff --git a/OpenSim/Data/SQLite/SQLiteAssetData.cs b/OpenSim/Data/SQLite/SQLiteAssetData.cs
index 16e560c..75e51a3 100644
--- a/OpenSim/Data/SQLite/SQLiteAssetData.cs
+++ b/OpenSim/Data/SQLite/SQLiteAssetData.cs
@@ -119,7 +119,7 @@ namespace OpenSim.Data.SQLite
119 /// Create an asset 119 /// Create an asset
120 /// </summary> 120 /// </summary>
121 /// <param name="asset">Asset Base</param> 121 /// <param name="asset">Asset Base</param>
122 override public void StoreAsset(AssetBase asset) 122 override public bool StoreAsset(AssetBase asset)
123 { 123 {
124 //m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString()); 124 //m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString());
125 if (ExistsAsset(asset.FullID)) 125 if (ExistsAsset(asset.FullID))
@@ -141,6 +141,7 @@ namespace OpenSim.Data.SQLite
141 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); 141 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
142 142
143 cmd.ExecuteNonQuery(); 143 cmd.ExecuteNonQuery();
144 return true;
144 } 145 }
145 } 146 }
146 } 147 }
@@ -161,6 +162,7 @@ namespace OpenSim.Data.SQLite
161 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); 162 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
162 163
163 cmd.ExecuteNonQuery(); 164 cmd.ExecuteNonQuery();
165 return true;
164 } 166 }
165 } 167 }
166 } 168 }
diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs
index df50902..3da298b 100644
--- a/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs
+++ b/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs
@@ -119,7 +119,7 @@ namespace OpenSim.Data.SQLiteLegacy
119 /// Create an asset 119 /// Create an asset
120 /// </summary> 120 /// </summary>
121 /// <param name="asset">Asset Base</param> 121 /// <param name="asset">Asset Base</param>
122 override public void StoreAsset(AssetBase asset) 122 override public bool StoreAsset(AssetBase asset)
123 { 123 {
124 //m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString()); 124 //m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString());
125 if (ExistsAsset(asset.FullID)) 125 if (ExistsAsset(asset.FullID))
@@ -139,6 +139,7 @@ namespace OpenSim.Data.SQLiteLegacy
139 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); 139 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
140 140
141 cmd.ExecuteNonQuery(); 141 cmd.ExecuteNonQuery();
142 return true;
142 } 143 }
143 } 144 }
144 } 145 }
@@ -157,6 +158,7 @@ namespace OpenSim.Data.SQLiteLegacy
157 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); 158 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
158 159
159 cmd.ExecuteNonQuery(); 160 cmd.ExecuteNonQuery();
161 return true;
160 } 162 }
161 } 163 }
162 } 164 }
diff --git a/OpenSim/Framework/AssetBase.cs b/OpenSim/Framework/AssetBase.cs
index 53d28be..98fa846 100644
--- a/OpenSim/Framework/AssetBase.cs
+++ b/OpenSim/Framework/AssetBase.cs
@@ -60,6 +60,8 @@ namespace OpenSim.Framework
60 /// </summary> 60 /// </summary>
61 private AssetMetadata m_metadata; 61 private AssetMetadata m_metadata;
62 62
63 private int m_uploadAttempts;
64
63 // This is needed for .NET serialization!!! 65 // This is needed for .NET serialization!!!
64 // Do NOT "Optimize" away! 66 // Do NOT "Optimize" away!
65 public AssetBase() 67 public AssetBase()
@@ -197,6 +199,12 @@ namespace OpenSim.Framework
197 set { m_metadata.Type = value; } 199 set { m_metadata.Type = value; }
198 } 200 }
199 201
202 public int UploadAttempts
203 {
204 get { return m_uploadAttempts; }
205 set { m_uploadAttempts = value; }
206 }
207
200 /// <summary> 208 /// <summary>
201 /// Is this a region only asset, or does this exist on the asset server also 209 /// Is this a region only asset, or does this exist on the asset server also
202 /// </summary> 210 /// </summary>
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index 470a4dd..3122382 100644
--- a/OpenSim/Services/AssetService/AssetService.cs
+++ b/OpenSim/Services/AssetService/AssetService.cs
@@ -144,7 +144,10 @@ namespace OpenSim.Services.AssetService
144 public string Store(AssetBase asset) 144 public string Store(AssetBase asset)
145 { 145 {
146 //m_log.DebugFormat("[ASSET SERVICE]: Store asset {0} {1}", asset.Name, asset.ID); 146 //m_log.DebugFormat("[ASSET SERVICE]: Store asset {0} {1}", asset.Name, asset.ID);
147 m_Database.StoreAsset(asset); 147 if (!m_Database.StoreAsset(asset))
148 {
149 return UUID.Zero.ToString();
150 }
148 151
149 return asset.ID; 152 return asset.ID;
150 } 153 }
diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
index 65b3537..ae600bb 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;
@@ -48,7 +49,9 @@ namespace OpenSim.Services.Connectors
48 49
49 private string m_ServerURI = String.Empty; 50 private string m_ServerURI = String.Empty;
50 private IImprovedAssetCache m_Cache = null; 51 private IImprovedAssetCache m_Cache = null;
51 52 private int m_retryCounter;
53 private Dictionary<int, List<AssetBase>> m_retryQueue = new Dictionary<int, List<AssetBase>>();
54 private Timer m_retryTimer;
52 public AssetServicesConnector() 55 public AssetServicesConnector()
53 { 56 {
54 } 57 }
@@ -85,6 +88,55 @@ namespace OpenSim.Services.Connectors
85 MainConsole.Instance.Commands.AddCommand("asset", false, "dump asset", 88 MainConsole.Instance.Commands.AddCommand("asset", false, "dump asset",
86 "dump asset <id> <file>", 89 "dump asset <id> <file>",
87 "dump one cached asset", HandleDumpAsset); 90 "dump one cached asset", HandleDumpAsset);
91
92 m_retryTimer = new Timer();
93 m_retryTimer.Elapsed += new ElapsedEventHandler(retryCheck);
94 m_retryTimer.Interval = 60000;
95 }
96
97 protected void retryCheck(object source, ElapsedEventArgs e)
98 {
99 m_retryCounter++;
100 if (m_retryCounter > 60) m_retryCounter -= 60;
101 List<int> keys = new List<int>();
102 foreach (int a in m_retryQueue.Keys)
103 {
104 keys.Add(a);
105 }
106 foreach (int a in keys)
107 {
108 //We exponentially fall back on frequency until we reach one attempt per hour
109 //The net result is that we end up in the queue for roughly 24 hours..
110 //24 hours worth of assets could be a lot, so the hope is that the region admin
111 //will have gotten the asset connector back online quickly!
112
113 int timefactor = a ^ 2;
114 if (timefactor > 60)
115 {
116 timefactor = 60;
117 }
118
119 //First, find out if we care about this timefactor
120 if (timefactor % a == 0)
121 {
122 //Yes, we do!
123 List<AssetBase> retrylist = m_retryQueue[a];
124 m_retryQueue.Remove(a);
125
126 foreach(AssetBase ass in retrylist)
127 {
128 Store(ass); //Store my ass. This function will put it back in the dictionary if it fails
129 }
130 }
131 }
132
133 if (m_retryQueue.Count == 0)
134 {
135 //It might only be one tick per minute, but I have
136 //repented and abandoned my wasteful ways
137 m_retryCounter = 0;
138 m_retryTimer.Stop();
139 }
88 } 140 }
89 141
90 protected void SetCache(IImprovedAssetCache cache) 142 protected void SetCache(IImprovedAssetCache cache)
@@ -222,20 +274,45 @@ namespace OpenSim.Services.Connectors
222 } 274 }
223 catch (Exception e) 275 catch (Exception e)
224 { 276 {
225 m_log.WarnFormat("[ASSET CONNECTOR]: Unable to send asset {0} to asset server. Reason: {1}", asset.ID, e.Message); 277 newID = UUID.Zero.ToString();
226 } 278 }
227 279
228 if (newID != String.Empty) 280 if (newID == UUID.Zero.ToString())
229 { 281 {
230 // Placing this here, so that this work with old asset servers that don't send any reply back 282 //The asset upload failed, put it in a queue for later
231 // SynchronousRestObjectRequester returns somethins that is not an empty string 283 asset.UploadAttempts++;
232 if (newID != null) 284 if (asset.UploadAttempts > 30)
233 asset.ID = newID; 285 {
234 286 //By this stage we've been in the queue for a good few hours;
235 if (m_Cache != null) 287 //We're going to drop the asset.
236 m_Cache.Cache(asset); 288 m_log.ErrorFormat("[Assets] Dropping asset {0} - Upload has been in the queue for too long.", asset.ID.ToString());
289 }
290 else
291 {
292 if (!m_retryQueue.ContainsKey(asset.UploadAttempts))
293 {
294 m_retryQueue.Add(asset.UploadAttempts, new List<AssetBase>());
295 }
296 List<AssetBase> m_queue = m_retryQueue[asset.UploadAttempts];
297 m_queue.Add(asset);
298 m_log.WarnFormat("[Assets] Upload failed: {0} - Requeuing asset for another run.", asset.ID.ToString());
299 m_retryTimer.Start();
300 }
301 }
302 else
303 {
304 if (newID != String.Empty)
305 {
306 // Placing this here, so that this work with old asset servers that don't send any reply back
307 // SynchronousRestObjectRequester returns somethins that is not an empty string
308 if (newID != null)
309 asset.ID = newID;
310
311 if (m_Cache != null)
312 m_Cache.Cache(asset);
313 }
237 } 314 }
238 return newID; 315 return asset.ID;
239 } 316 }
240 317
241 public bool UpdateContent(string id, byte[] data) 318 public bool UpdateContent(string id, byte[] data)
diff --git a/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs
index 4a15cf2..5bab62c 100644
--- a/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs
+++ b/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs
@@ -54,9 +54,10 @@ namespace OpenSim.Tests.Common.Mock
54 return assets.Find(x=>x.FullID == uuid); 54 return assets.Find(x=>x.FullID == uuid);
55 } 55 }
56 56
57 public void StoreAsset(AssetBase asset) 57 public bool StoreAsset(AssetBase asset)
58 { 58 {
59 assets.Add(asset); 59 assets.Add(asset);
60 return true;
60 } 61 }
61 62
62 public List<AssetMetadata> FetchAssetMetadataSet(int start, int count) { return new List<AssetMetadata>(count); } 63 public List<AssetMetadata> FetchAssetMetadataSet(int start, int count) { return new List<AssetMetadata>(count); }