aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2014-11-06 01:15:22 +0000
committerJustin Clark-Casey (justincc)2014-11-25 23:23:11 +0000
commitaeae34505f5f306bbf4d9f3db19db8a26ac5e63d (patch)
tree1a6afdaeb024dc9ffa60cf98e9f53afc1f992c96
parentIntroduce an IteratingUuidGatherer where each fetch from the asset service (i... (diff)
downloadopensim-SC_OLD-aeae34505f5f306bbf4d9f3db19db8a26ac5e63d.zip
opensim-SC_OLD-aeae34505f5f306bbf4d9f3db19db8a26ac5e63d.tar.gz
opensim-SC_OLD-aeae34505f5f306bbf4d9f3db19db8a26ac5e63d.tar.bz2
opensim-SC_OLD-aeae34505f5f306bbf4d9f3db19db8a26ac5e63d.tar.xz
When processing incoming attachments via HG, if a request for uuid gathering or final asset import takes too long remove remaining requests from same user to prevent hold up of other user's incoming attachments.
This improves upon the earlier naive simply queueing immplementation. Threshold is 30 seconds. If this happens to a user they can relog and fetch will be reattempted.
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs96
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs31
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs21
-rw-r--r--OpenSim/Services/HypergridService/HGAssetService.cs2
4 files changed, 121 insertions, 29 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index be409bb..7e356ea 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -546,6 +546,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
546 } 546 }
547 } 547 }
548 548
549 private void RemoveIncomingSceneObjectJobs(string commonIdToRemove)
550 {
551 List<Job> jobsToReinsert = new List<Job>();
552 int jobsRemoved = 0;
553
554 Job job;
555 while ((job = m_incomingSceneObjectEngine.RemoveNextRequest()) != null)
556 {
557 if (job.CommonId != commonIdToRemove)
558 jobsToReinsert.Add(job);
559 else
560 jobsRemoved++;
561 }
562
563 m_log.DebugFormat(
564 "[HG ENTITY TRANSFER]: Removing {0} jobs with common ID {1} and reinserting {2} other jobs",
565 jobsRemoved, commonIdToRemove, jobsToReinsert.Count);
566
567 if (jobsToReinsert.Count > 0)
568 {
569 foreach (Job jobToReinsert in jobsToReinsert)
570 m_incomingSceneObjectEngine.QueueRequest(jobToReinsert);
571 }
572 }
573
549 public override bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition) 574 public override bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition)
550 { 575 {
551 // FIXME: We must make it so that we can use SOG.IsAttachment here. At the moment it is always null! 576 // FIXME: We must make it so that we can use SOG.IsAttachment here. At the moment it is always null!
@@ -564,38 +589,73 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
564 { 589 {
565 m_incomingSceneObjectEngine.QueueRequest( 590 m_incomingSceneObjectEngine.QueueRequest(
566 string.Format("HG UUID Gather for attachment {0} for {1}", so.Name, aCircuit.Name), 591 string.Format("HG UUID Gather for attachment {0} for {1}", so.Name, aCircuit.Name),
592 so.OwnerID.ToString(),
567 o => 593 o =>
568 { 594 {
569 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); 595 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
570 m_log.DebugFormat( 596// m_log.DebugFormat(
571 "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset server {2}", 597// "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset service {2}",
572 so.Name, so.AttachedAvatar, url); 598// so.Name, so.AttachedAvatar, url);
573 599
574 IteratingHGUuidGatherer uuidGatherer = new IteratingHGUuidGatherer(Scene.AssetService, url); 600 IteratingHGUuidGatherer uuidGatherer = new IteratingHGUuidGatherer(Scene.AssetService, url);
575 uuidGatherer.RecordAssetUuids(so); 601 uuidGatherer.RecordAssetUuids(so);
576 602
577 // XXX: We will shortly use this iterating mechanism to check if a fetch is taking too long 603 while (!uuidGatherer.Complete)
578 // but just for now we will simply fetch everything. If this was permanent could use 604 {
579 // GatherAll() 605 int tickStart = Util.EnvironmentTickCount();
580 while (uuidGatherer.GatherNext()) 606
581 m_log.DebugFormat( 607 UUID? nextUuid = uuidGatherer.NextUuidToInspect;
582 "[HG ENTITY TRANSFER]: Gathered attachment {0} for HG user {1} with asset server {2}", 608 uuidGatherer.GatherNext();
583 so.Name, so.OwnerID, url); 609
610// m_log.DebugFormat(
611// "[HG ENTITY TRANSFER]: Gathered attachment asset uuid {0} for object {1} for HG user {2} took {3} ms with asset service {4}",
612// nextUuid, so.Name, so.OwnerID, Util.EnvironmentTickCountSubtract(tickStart), url);
613
614 int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart);
615
616 if (ticksElapsed > 30000)
617 {
618 m_log.WarnFormat(
619 "[HG ENTITY TRANSFER]: Removing incoming scene object jobs for HG user {0} as gather of {1} from {2} took {3} ms to respond (> {4} ms)",
620 so.OwnerID, so.Name, url, ticksElapsed, 30000);
621
622 RemoveIncomingSceneObjectJobs(so.OwnerID.ToString());
623
624 return;
625 }
626 }
584 627
585 IDictionary<UUID, sbyte> ids = uuidGatherer.GetGatheredUuids(); 628 IDictionary<UUID, sbyte> ids = uuidGatherer.GetGatheredUuids();
586 629
587 m_log.DebugFormat( 630// m_log.DebugFormat(
588 "[HG ENTITY TRANSFER]: Fetching {0} assets for attachment {1} for HG user {2} with asset server {3}", 631// "[HG ENTITY TRANSFER]: Fetching {0} assets for attachment {1} for HG user {2} with asset service {3}",
589 ids.Count, so.Name, so.OwnerID, url); 632// ids.Count, so.Name, so.OwnerID, url);
590 633
591 foreach (KeyValuePair<UUID, sbyte> kvp in ids) 634 foreach (KeyValuePair<UUID, sbyte> kvp in ids)
592 uuidGatherer.FetchAsset(kvp.Key); 635 {
636 int tickStart = Util.EnvironmentTickCount();
637
638 uuidGatherer.FetchAsset(kvp.Key);
639
640 int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart);
641
642 if (ticksElapsed > 30000)
643 {
644 m_log.WarnFormat(
645 "[HG ENTITY TRANSFER]: Removing incoming scene object jobs for HG user {0} as fetch of {1} from {2} took {3} ms to respond (> {4} ms)",
646 so.OwnerID, kvp.Key, url, ticksElapsed, 30000);
647
648 RemoveIncomingSceneObjectJobs(so.OwnerID.ToString());
649
650 return;
651 }
652 }
593 653
594 base.HandleIncomingSceneObject(so, newPosition); 654 base.HandleIncomingSceneObject(so, newPosition);
595 655
596 m_log.DebugFormat( 656// m_log.DebugFormat(
597 "[HG ENTITY TRANSFER MODULE]: Completed incoming attachment {0} for HG user {1} with asset server {2}", 657// "[HG ENTITY TRANSFER MODULE]: Completed incoming attachment {0} for HG user {1} with asset server {2}",
598 so.Name, so.OwnerID, url); 658// so.Name, so.OwnerID, url);
599 }, 659 },
600 null); 660 null);
601 } 661 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs
index 718db31..ce6cdc9 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs
@@ -38,13 +38,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
38{ 38{
39 public class Job 39 public class Job
40 { 40 {
41 public string Name; 41 public string Name { get; private set; }
42 public WaitCallback Callback; 42 public string CommonId { get; private set; }
43 public object O; 43 public WaitCallback Callback { get; private set; }
44 public object O { get; private set; }
44 45
45 public Job(string name, WaitCallback callback, object o) 46 public Job(string name, string commonId, WaitCallback callback, object o)
46 { 47 {
47 Name = name; 48 Name = name;
49 CommonId = commonId;
48 Callback = callback; 50 Callback = callback;
49 O = o; 51 O = o;
50 } 52 }
@@ -90,6 +92,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
90 92
91 public HGIncomingSceneObjectEngine(string name) 93 public HGIncomingSceneObjectEngine(string name)
92 { 94 {
95// LogLevel = 1;
93 Name = name; 96 Name = name;
94 RequestProcessTimeoutOnStop = 5000; 97 RequestProcessTimeoutOnStop = 5000;
95 98
@@ -192,10 +195,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
192 } 195 }
193 } 196 }
194 197
195 public bool QueueRequest(string name, WaitCallback req, object o) 198 public Job RemoveNextRequest()
199 {
200 Job nextRequest;
201 m_requestQueue.TryTake(out nextRequest);
202
203 return nextRequest;
204 }
205
206 public bool QueueRequest(string name, string commonId, WaitCallback req, object o)
207 {
208 return QueueRequest(new Job(name, commonId, req, o));
209 }
210
211 public bool QueueRequest(Job job)
196 { 212 {
197 if (LogLevel >= 1) 213 if (LogLevel >= 1)
198 m_log.DebugFormat("[HG INCOMING SCENE OBJECT ENGINE]: Queued job {0}", name); 214 m_log.DebugFormat(
215 "[HG INCOMING SCENE OBJECT ENGINE]: Queued job {0}, common ID {1}", job.Name, job.CommonId);
199 216
200 if (m_requestQueue.Count < m_requestQueue.BoundedCapacity) 217 if (m_requestQueue.Count < m_requestQueue.BoundedCapacity)
201 { 218 {
@@ -203,7 +220,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
203 // "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}", 220 // "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}",
204 // categories, client.AgentID, m_udpServer.Scene.Name); 221 // categories, client.AgentID, m_udpServer.Scene.Name);
205 222
206 m_requestQueue.Add(new Job(name, req, o)); 223 m_requestQueue.Add(job);
207 224
208 if (!m_warnOverMaxQueue) 225 if (!m_warnOverMaxQueue)
209 m_warnOverMaxQueue = true; 226 m_warnOverMaxQueue = true;
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index 9c4e4c0..2450cdb 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -655,7 +655,22 @@ namespace OpenSim.Region.Framework.Scenes
655 /// <summary> 655 /// <summary>
656 /// Is gathering complete? 656 /// Is gathering complete?
657 /// </summary> 657 /// </summary>
658 public bool GatheringComplete { get { return m_assetUuidsToInspect.Count <= 0; } } 658 public bool Complete { get { return m_assetUuidsToInspect.Count <= 0; } }
659
660 /// <summary>
661 /// Gets the next UUID to inspect.
662 /// </summary>
663 /// <value>If there is no next UUID then returns null</value>
664 public UUID? NextUuidToInspect
665 {
666 get
667 {
668 if (Complete)
669 return null;
670 else
671 return m_assetUuidsToInspect.Peek();
672 }
673 }
659 674
660 protected IAssetService m_assetService; 675 protected IAssetService m_assetService;
661 676
@@ -693,7 +708,7 @@ namespace OpenSim.Region.Framework.Scenes
693 /// <returns>false if gathering is already complete, true otherwise</returns> 708 /// <returns>false if gathering is already complete, true otherwise</returns>
694 public bool GatherNext() 709 public bool GatherNext()
695 { 710 {
696 if (GatheringComplete) 711 if (Complete)
697 return false; 712 return false;
698 713
699 GetAssetUuids(m_assetUuidsToInspect.Dequeue()); 714 GetAssetUuids(m_assetUuidsToInspect.Dequeue());
@@ -707,7 +722,7 @@ namespace OpenSim.Region.Framework.Scenes
707 /// <returns>false if gathering is already complete, true otherwise</returns> 722 /// <returns>false if gathering is already complete, true otherwise</returns>
708 public bool GatherAll() 723 public bool GatherAll()
709 { 724 {
710 if (GatheringComplete) 725 if (Complete)
711 return false; 726 return false;
712 727
713 while (GatherNext()); 728 while (GatherNext());
diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs
index 5c804d4..b57f8d8 100644
--- a/OpenSim/Services/HypergridService/HGAssetService.cs
+++ b/OpenSim/Services/HypergridService/HGAssetService.cs
@@ -100,7 +100,7 @@ namespace OpenSim.Services.HypergridService
100 return null; 100 return null;
101 101
102 if (asset.Metadata.Type == (sbyte)AssetType.Object) 102 if (asset.Metadata.Type == (sbyte)AssetType.Object)
103 asset.Data = AdjustIdentifiers(asset.Data); ; 103 asset.Data = AdjustIdentifiers(asset.Data);
104 104
105 AdjustIdentifiers(asset.Metadata); 105 AdjustIdentifiers(asset.Metadata);
106 106