Ejemplo n.º 1
0
        /// <summary>
        /// Processes the result of fetching an individual file.
        /// </summary>
        /// <param name="state">Indicates the state of the ongoing fetch operation (as set up in FetchObj).</param>
        /// <param name="index">If ROOT_FILE_INDEX, then this is a result for the main file; else this is a result for
        /// the resource file with that index.</param>
        /// <param name="status">The status indicating if the download succeed</param>
        /// <param name="data">The data that was downloaded.</param>
        private void ProcessFileFetchResult(FetchOperationState state, int index, PolyStatus status, byte[] data)
        {
            if (state.pendingFiles == 0)
            {
                // Another request for this format failed, so we ignore any further responses.
                return;
            }

            if (!status.ok)
            {
                // This request failed, so we set pendingFiles to 0 so we ignore any further responses, and callback with
                // an error message.
                state.pendingFiles = 0;
                state.completionCallback(state.asset, PolyStatus.Error(status, "Failed to fetch file #{0}", index));
                return;
            }

            PolyFormat package = state.packageBeingFetched;
            PolyFile   file    = index == ROOT_FILE_INDEX ? package.root : package.resources[index];

            file.contents = data;

            --state.pendingFiles;
            if (state.progressCallback != null)
            {
                state.progressCallback(state.asset, 1.0f - ((float)state.pendingFiles / state.totalFiles));
            }
            if (state.pendingFiles <= 0)
            {
                // All files done, call callback indicating success.
                state.completionCallback(state.asset, PolyStatus.Success());
            }
        }
Ejemplo n.º 2
0
        public void FetchFormatFiles(PolyAsset asset, PolyFormatType formatType,
                                     PolyApi.FetchFormatFilesCallback completionCallback, FetchProgressCallback progressCallback = null)
        {
            PolyUtils.AssertNotNull(asset, "Asset can't be null.");
            PolyUtils.AssertNotNull(formatType, "formatType can't be null.");
            PolyFormat packageToFetch = asset.GetFormatIfExists(formatType);

            if (packageToFetch == null)
            {
                if (completionCallback != null)
                {
                    completionCallback(asset, PolyStatus.Error("Format type not present in asset"));
                }
                return;
            }

            PolyUtils.AssertNotNull(packageToFetch.root, "packageToFetch.root can't be null.");
            PolyUtils.AssertNotNull(packageToFetch.root.url, "packageToFetch.root.url can't be null.");
            PolyUtils.AssertNotNull(packageToFetch.resources, "packageToFetch.resources can't be null.");

            string accessToken = GetAccessToken();

            FetchOperationState state = new FetchOperationState();

            state.asset = asset;
            state.completionCallback  = completionCallback;
            state.progressCallback    = progressCallback;
            state.packageBeingFetched = packageToFetch;

            // Indicates how many files are pending download (1 for main file + 1 for each resource).
            state.totalFiles = state.pendingFiles = 1 + packageToFetch.resources.Count;

            // Note that the callbacks are asynchronous so they may complete in any order.  What we do know is that they
            // will all be called on the main thread, so they won't be called concurrently.

            long maxCacheAge = asset.IsMutable ? MUTABLE_ASSET_MAX_CACHE_AGE : IMMUTABLE_ASSET_MAX_CACHE_AGE;

            PolyClientUtils.GetRawFileBytes(packageToFetch.root.url, accessToken, maxCacheAge,
                                            (PolyStatus status, byte[] data) => { ProcessFileFetchResult(state, ROOT_FILE_INDEX, status, data); });

            for (int i = 0; i < packageToFetch.resources.Count; i++)
            {
                int thisIndex = i; // copy of variable, for closure below.
                PolyClientUtils.GetRawFileBytes(packageToFetch.resources[i].url, accessToken, maxCacheAge,
                                                (status, data) => { ProcessFileFetchResult(state, thisIndex, status, data); });
            }
        }
Ejemplo n.º 3
0
        public DataTable ExCommandToDatatableNew(DbCommand cmdX, string Name, string Namespace, int timeout_seconds)
        {
            Tracing.VerboseDAL(cmdX.CommandText);

            /* [dlatikay 20160801] I-1606-2237 site of ultimate improvement of (not done yet, considered MemoryFailPoint)
             * [dlatikay 20160909] I-1609-1674, MEA-2016-00401: this primordial version proved to be the fastest */
            if (timeout_seconds > 0)
            {
                /* we need to roll our own timeout,
                 * would be must easier with 4.5, but as we're still stuck with 4.0 (also for MONO compatibility reasons), we're inspired by:
                 * http://stackoverflow.com/questions/18760252/timeout-an-async-method-implemented-with-taskcompletionsource/18760624#18760624 */
                var parms = new FetchOperationState()
                {
                    cmdX            = cmdX,
                    Name            = Name,
                    Namespace       = Namespace,
                    timeout_seconds = timeout_seconds
                };
                try
                {
                    /* we give the envelope one second more time,
                     * so the underlying RDBMS client code has the chance to not fail to recognize its own timeout, as it should (but does not,
                     * at least not Managed Oracle, as we painfully found out) */
                    FetchOperationAsync(parms, CancellationToken.None, timeout_seconds + 1).Wait();
                }
                catch (Exception tox)
                {
#if DEBUG
                    Tracing.WarningDAL("{0}", tox.ToString());
#endif
                    while (tox is AggregateException)
                    {
                        tox = tox.InnerException;
                    }
                    if (tox is TaskCanceledException)
                    {
                        throw new TimeoutException(String.Format("DAL DB Timeout expired ({0}sec)", timeout_seconds), tox);
                    }
                }
                return(parms.dt);
            }
            else
            {
                /* simple synchronous variant */
                using (DbDataAdapter ad = db.NewDataAdapter())
                {
                    ad.SelectCommand = cmdX;
                    var dt = new DataTable(Name, Namespace);
                    ad.Fill(dt);
                    return(dt);
                }
            }
            /* unfortunately, this by far cuter variant is considerable slower (>30%)! */
            //if (timeout_seconds > 0) cmdX.CommandTimeout = timeout_seconds;
            //using (var dr = cmdX.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SingleResult))
            //{
            //    var dt = new DataTable(Name, Namespace);
            //    dt.Load(dr, LoadOption.OverwriteChanges, (s, e) =>
            //    {
            //        if (e.Errors != null) Tracing.VerboseDAL("dt.load.error {0}", e.Errors.ToString());
            //    });
            //    foreach (DataColumn col in dt.Columns)
            //    {
            //        col.ReadOnly = false; /* http://stackoverflow.com/questions/5434833/readonlyexception-datatable-datarow-column-x-is-read-only */
            //        if (col.MaxLength > 0) col.MaxLength = -1; /* https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(System.Data.DataColumn.MaxLength);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.0);k(DevLang-csharp)&rd=true */
            //    }
            //    return dt;
            //}
        }