public static void GetBytes(string url, Action <CacheWebResponse <byte[]> > onBytesDownloaded,
                                    Func <string, bool> isRequestCancelled)
        {
            BetterThreadPool.QueueUserWorkItem(state =>
            {
                var response = new CacheWebResponse <byte[]>();
                if (!isRequestCancelled(url))
                {
                    response.Status = CacheWebResponseStatus.Cancelled;
                }
                else
                {
                    var cachePath = GetCacheFilePath(url);
                    if (_cacheFileIndex.ContainsKey(cachePath))
                    {
                        try
                        {
                            response.Content    = File.ReadAllBytes(cachePath);
                            response.IsCacheHit = true;
                            response.Status     = CacheWebResponseStatus.Success;
                            BetterThreadPool.QueueUserWorkItem(notUsed => { InsertOrUpdateCacheEntry(cachePath); });
                        }
                        catch (IOException ioException)
                        {
                            response.Status       = CacheWebResponseStatus.Error;
                            response.ErrorMessage = ioException.Message;
                        }
                    }
                    else
                    {
#if !UNITY_WSA || UNITY_EDITOR// We do not have WebClient in Windows Store Apps
                        var client = new TimeoutWebClient();
                        // set a proxy if one was used
                        if (!string.IsNullOrEmpty(_proxyUrl))
                        {
                            client.Proxy = new WebProxy(_proxyUrl);
                        }
                        try
                        {
                            response.Content = client.DownloadData(url);
                            response.Status  = CacheWebResponseStatus.Success;
                            BetterThreadPool.QueueUserWorkItem(
                                s => { SaveResponseToFileCache(cachePath, response.Content); });
                        }
                        catch (WebException wex)
                        {
                            response.Status       = CacheWebResponseStatus.Error;
                            response.ErrorMessage = wex.ToString();
                        }
#else
                        Debug.LogError("This should not execute.");
#endif
                    }
                }
                onBytesDownloaded(response);
            });
        }
Beispiel #2
0
 public static bool InitInstance(int queueSize, int threadNum)
 {
     if (Instance != null)
     {
         Debug.LogWarning("TreadPool instance is already created.");
         return(false);
     }
     Instance = new BetterThreadPool(queueSize, threadNum);
     return(true);
 }
Beispiel #3
0
 static BetterThreadPool()
 {
     Instance = null;
 }
        // Responsible for getting the geometry data for a given request
        // The method works roughly as follows
        // 1. Check if model data is in cache
        //    a. If not, start a web request for the data and add this request to the dependency list for the path
        // 2. If the model data cache indicates that it is being filled (a set value of null) (including if the request
        //      just started during this invocation) add the request to the dependency list for this path
        // 3. If the model is in the cache and set then get the data for the request and move it forward
        private IEnumerator GetModelForRequest(LoadCubeRequest loadRequest)
        {
            var modelPath = loadRequest.Query.GetModelPath(loadRequest.LodIndex, loadRequest.X, loadRequest.Y,
                                                           loadRequest.Z, ModelFormatString);

            while (!Monitor.TryEnter(_geometryBufferCache))
            {
                yield return(null);
            }
            // If the geometry data is being loaded or this is the first request to load it add the request the dependency list
            if (!_geometryBufferCache.ContainsKey(modelPath) || _geometryBufferCache[modelPath] == null)
            {
                yield return(StartCoroutine(AddDependentRequest(loadRequest, modelPath)));

                if (!_geometryBufferCache.ContainsKey(modelPath))
                {
                    // Model data was not present in cache nor has any request started constructing it
                    GeometryCacheMisses++;

                    _geometryBufferCache[modelPath] = null;
                    Monitor.Exit(_geometryBufferCache);
                    if (UseWwwForEbo)
                    {
                        var cachePath = CacheWebRequest.GetCacheFilePath(modelPath);
                        WWW modelWww;
                        if (CacheWebRequest.IsItemInCache(cachePath))
                        {
                            FileCacheHits++;
                            modelWww = new WWW("file:///" + cachePath);
                            yield return(modelWww);
                        }
                        else
                        {
                            FileCacheMisses++;
                            modelWww = new WWW(modelPath);
                            yield return(modelWww);

                            if (modelWww.Succeeded())
                            {
                                CacheWebRequest.AddToCache(cachePath, modelWww.bytes);
                            }
                        }

                        if (modelWww.Failed())
                        {
                            Debug.LogError("Error getting model [" + modelPath + "] " +
                                           modelWww.error);
                            FailGetGeometryBufferRequest(loadRequest, modelPath);
                        }
                        else
                        {
                            var buffer =
                                new GeometryBuffer(_geometryBufferAltitudeTransform, true)
                            {
                                Buffer = modelWww.bytes,
                                Format = ModelFormat
                            };
                            BetterThreadPool.QueueUserWorkItem(s =>
                            {
                                buffer.Process();
                                lock (_geometryBufferCache)
                                {
                                    _geometryBufferCache[modelPath] = buffer;
                                }
                                SucceedGetGeometryBufferRequest(modelPath, buffer).Wait();
                            });
                        }
                    }
                    else
                    {
                        CacheWebRequest.GetBytes(modelPath, modelResponse =>
                        {
                            lock (_geometryBufferCache)
                            {
                                if (modelResponse.Status == CacheWebRequest.CacheWebResponseStatus.Error)
                                {
                                    Debug.LogError("Error getting model [" + modelPath + "] " +
                                                   modelResponse.ErrorMessage);
                                    FailGetGeometryBufferRequest(loadRequest, modelPath);
                                }
                                else if (modelResponse.Status == CacheWebRequest.CacheWebResponseStatus.Cancelled)
                                {
                                    _geometryBufferCache.Remove(modelPath);
                                }
                                else
                                {
                                    if (modelResponse.IsCacheHit)
                                    {
                                        FileCacheHits++;
                                    }
                                    else
                                    {
                                        FileCacheMisses++;
                                    }
                                    var buffer = new GeometryBuffer(_geometryBufferAltitudeTransform, true)
                                    {
                                        Buffer = modelResponse.Content,
                                        Format = ModelFormat
                                    };
                                    buffer.Process();
                                    _geometryBufferCache[modelPath] = buffer;
                                    SucceedGetGeometryBufferRequest(modelPath, buffer).Wait();
                                }
                            }
                        }, DependentRequestsExistBlocking);
                    }
                }
                else
                {
                    Monitor.Exit(_geometryBufferCache);
                }
            }
            else // The model data was in the cache
            {
                // Model was constructed move request to next step
                GeometryCacheHits++;
                loadRequest.GeometryBuffer = _geometryBufferCache[modelPath];
                MoveRequestForward(loadRequest);
                Monitor.Exit(_geometryBufferCache);
            }
        }
 static CacheWebRequest()
 {
     BetterThreadPool.InitInstance();
     InitializeCache(DefaultMaxCacheSize);
 }
 public static void AddToCache(string cacheKey, byte[] content)
 {
     BetterThreadPool.QueueUserWorkItem(s => { SaveResponseToFileCache(cacheKey, content); });
 }