When an uncached asset is requested multiple times concurrently, only load it once
Signed-off-by: root <root@grid00001.t-data.com>bulletsim
							parent
							
								
									56830bfe07
								
							
						
					
					
						commit
						71ef4a8fb3
					
				| 
						 | 
				
			
			@ -48,6 +48,13 @@ namespace OpenSim.Services.Connectors
 | 
			
		|||
        private string m_ServerURI = String.Empty;
 | 
			
		||||
        private IImprovedAssetCache m_Cache = null;
 | 
			
		||||
 | 
			
		||||
        private delegate void AssetRetrievedEx(AssetBase asset);
 | 
			
		||||
 | 
			
		||||
        // Keeps track of concurrent requests for the same asset, so that it's only loaded once.
 | 
			
		||||
        // Maps: Asset ID -> Handlers which will be called when the asset has been loaded
 | 
			
		||||
        private Dictionary<string, AssetRetrievedEx> m_AssetHandlers = new Dictionary<string, AssetRetrievedEx>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public AssetServicesConnector()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -178,23 +185,56 @@ namespace OpenSim.Services.Connectors
 | 
			
		|||
 | 
			
		||||
            if (asset == null)
 | 
			
		||||
            {
 | 
			
		||||
                bool result = false;
 | 
			
		||||
                lock (m_AssetHandlers)
 | 
			
		||||
                {
 | 
			
		||||
                    AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate(AssetBase _asset) { handler(id, sender, _asset); });
 | 
			
		||||
 | 
			
		||||
                AsynchronousRestObjectRequester.
 | 
			
		||||
                        MakeRequest<int, AssetBase>("GET", uri, 0,
 | 
			
		||||
                    AssetRetrievedEx handlers;
 | 
			
		||||
                    if (m_AssetHandlers.TryGetValue(id, out handlers))
 | 
			
		||||
                    {
 | 
			
		||||
                        // Someone else is already loading this asset. It will notify our handler when done.
 | 
			
		||||
                        handlers += handlerEx;
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Load the asset ourselves
 | 
			
		||||
                    handlers += handlerEx;
 | 
			
		||||
                    m_AssetHandlers.Add(id, handlers);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                bool success = false;
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    AsynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0,
 | 
			
		||||
                        delegate(AssetBase a)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (m_Cache != null)
 | 
			
		||||
                                m_Cache.Cache(a);
 | 
			
		||||
                            handler(id, sender, a);
 | 
			
		||||
                            result = true;
 | 
			
		||||
                        });
 | 
			
		||||
 | 
			
		||||
                return result;
 | 
			
		||||
                            AssetRetrievedEx handlers;
 | 
			
		||||
                            lock (m_AssetHandlers)
 | 
			
		||||
                            {
 | 
			
		||||
                                handlers = m_AssetHandlers[id];
 | 
			
		||||
                                m_AssetHandlers.Remove(id);
 | 
			
		||||
                            }
 | 
			
		||||
                            handlers.Invoke(a);
 | 
			
		||||
                        });
 | 
			
		||||
                    
 | 
			
		||||
                    success = true;
 | 
			
		||||
                }
 | 
			
		||||
                finally
 | 
			
		||||
                {
 | 
			
		||||
                    if (!success)
 | 
			
		||||
                    {
 | 
			
		||||
                        lock (m_AssetHandlers)
 | 
			
		||||
                        {
 | 
			
		||||
                            m_AssetHandlers.Remove(id);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                //Util.FireAndForget(delegate { handler(id, sender, asset); });
 | 
			
		||||
                handler(id, sender, asset);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue