private static void ChangeDetectedHandler(ChangeDetectedEventArg arg)
 {
     using (ChangeLock.Write())
     {
         /*
          * At any point of time there can't be no more than 2 change, corresponding
          * to the Config and Resource change type.
          * 
          * New change of the Resource change type will have its affected-resources
          * merged into existing change.
          */
         var change = Changes.FirstOrDefault(c => c.ChangeType == arg.ChangeType);
         if (change == null)
         {
             if (Log.IsDebugEnabled)
                 Log.Debug("Change posted. " + arg);
             Changes.Add(arg);
         }
         else if (arg.ChangeType == ChangeType.Resource)
         {
             foreach (var path in arg.ModifiedResourcePaths)
             {
                 if (!change.ModifiedResourcePaths.Contains(path))
                 {
                     change.ModifiedResourcePaths.Add(path);
                 }
             }
             if (Log.IsDebugEnabled)
                 Log.Debug("Change merged. " + change);
         }
     }
 }
Example #2
0
        private void OnChange(ChangeType changeType, List <string> affectedResources)
        {
            if (ChangeDetected == null)
            {
                return;
            }
            var arg = new ChangeDetectedEventArg(changeType, affectedResources);

            ChangeDetected(arg);
        }
Example #3
0
        private static void ApplyChange(ChangeDetectedEventArg change)
        {
            /*
             * We may be dealing with a new setting object not existing
             * when the change.ModifiedResourcePaths is created, the code should
             * make sure it deals with the latest resource sets only
             */
            var settings = ReadSettings();

            foreach (var set in settings.ResourceSets)
            {
                if (!set.IsAutoVersion)
                {
                    continue;
                }

                var modifiedResources = set.Where(
                    r => change.ModifiedResourcePaths.Any(
                        path => path.Equals(r.Path, StringComparison.OrdinalIgnoreCase)))
                                        .ToList();

                // Clear the content cache before recomputing the hash
                modifiedResources.ForEach(r => r.RemoveInCache());

                /*
                 * ComputeHash() must be kept out of the ConfigLock and ChangeLock in case
                 * it makes HTTP request to local dynamic resources which happen to
                 * require reading settings (i.e. invoke GetSettings()) and result in a
                 * deadlock.
                 *
                 * This type of lock-smart approach has an issue:
                 * - T1 finishes computing a hash
                 * - T2 picks up new change and finishes cimputing another hash
                 * - T2 save the hash
                 * - T1 save the hash -> this is the old hash
                 * But this shouldn't be a big deal because the only problem with it is
                 * when the app restarts and the new hash is recomputed, which is different
                 * from the hash in the client's browser cache and thus force the browser
                 * to make new request to the server.
                 */
                set.Hash = set.ComputeHash();
            }
        }
Example #4
0
 private static void ChangeDetectedHandler(ChangeDetectedEventArg arg)
 {
     using (ChangeLock.Write())
     {
         /*
          * At any point of time there can't be no more than 2 change, corresponding
          * to the Config and Resource change type.
          *
          * New change of the Resource change type will have its affected-resources
          * merged into existing change.
          */
         var change = Changes.FirstOrDefault(c => c.ChangeType == arg.ChangeType);
         if (change == null)
         {
             if (Log.IsDebugEnabled)
             {
                 Log.Debug("Change posted. " + arg);
             }
             Changes.Add(arg);
         }
         else if (arg.ChangeType == ChangeType.Resource)
         {
             foreach (var path in arg.ModifiedResourcePaths)
             {
                 if (!change.ModifiedResourcePaths.Contains(path))
                 {
                     change.ModifiedResourcePaths.Add(path);
                 }
             }
             if (Log.IsDebugEnabled)
             {
                 Log.Debug("Change merged. " + change);
             }
         }
     }
 }
Example #5
0
 public ChangeDetectedEventArg(ChangeDetectedEventArg other)
 {
     ChangeType            = other.ChangeType;
     ModifiedResourcePaths = new List <string>(other.ModifiedResourcePaths);
 }
        private static void ApplyChange(ChangeDetectedEventArg change)
        {
            /*
             * We may be dealing with a new setting object not existing
             * when the change.ModifiedResourcePaths is created, the code should
             * make sure it deals with the latest resource sets only
             */
            var settings = ReadSettings();
            foreach (var set in settings.ResourceSets)
            {
                if (!set.IsAutoVersion)
                    continue;
                var modifiedResources = set.Where(
                    r => change.ModifiedResourcePaths.Any(
                             path => path.Equals(r.Path, StringComparison.OrdinalIgnoreCase)))
                    .ToList();

                // Clear the content cache before recomputing the hash
                modifiedResources.ForEach(r => r.RemoveInCache());

                /*
                 * ComputeHash() must be kept out of the ConfigLock and ChangeLock in case 
                 * it makes HTTP request to local dynamic resources which happen to 
                 * require reading settings (i.e. invoke GetSettings()) and result in a 
                 * deadlock.  
                 * 
                 * This type of lock-smart approach has an issue:  
                 * - T1 finishes computing a hash
                 * - T2 picks up new change and finishes cimputing another hash
                 * - T2 save the hash
                 * - T1 save the hash -> this is the old hash
                 * But this shouldn't be a big deal because the only problem with it is
                 * when the app restarts and the new hash is recomputed, which is different
                 * from the hash in the client's browser cache and thus force the browser
                 * to make new request to the server.
                 */
                set.Hash = set.ComputeHash();
            }
        }
Example #7
0
 public ChangeDetectedEventArg(ChangeDetectedEventArg other)
 {
     ChangeType = other.ChangeType;
     ModifiedResourcePaths = new List<string>(other.ModifiedResourcePaths);
 }
Example #8
0
 private void OnChange(ChangeType changeType, List<string> affectedResources)
 {
     if (ChangeDetected == null)
         return;
     var arg = new ChangeDetectedEventArg(changeType, affectedResources);
     ChangeDetected(arg);
 }