diff options
author | Diva Canto | 2010-12-14 12:16:51 -0800 |
---|---|---|
committer | Diva Canto | 2010-12-14 12:16:51 -0800 |
commit | 10ae5454cbc0bb5ffab518203023d76abdd762cd (patch) | |
tree | ddff0f8302782cccfd3ac8195326fc68c9714eb4 /OpenSim | |
parent | More on mantis #5270 (diff) | |
download | opensim-SC-10ae5454cbc0bb5ffab518203023d76abdd762cd.zip opensim-SC-10ae5454cbc0bb5ffab518203023d76abdd762cd.tar.gz opensim-SC-10ae5454cbc0bb5ffab518203023d76abdd762cd.tar.bz2 opensim-SC-10ae5454cbc0bb5ffab518203023d76abdd762cd.tar.xz |
Made the map thread request the map items asynchronously, as the name suggested -- but with a cap of 20 async requests max at any given time.
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 80 |
1 files changed, 71 insertions, 9 deletions
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 6d9afce..e3ba190 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -33,6 +33,7 @@ using System.Drawing.Imaging; | |||
33 | using System.IO; | 33 | using System.IO; |
34 | using System.Net; | 34 | using System.Net; |
35 | using System.Reflection; | 35 | using System.Reflection; |
36 | using System.Runtime.Remoting.Messaging; | ||
36 | using System.Threading; | 37 | using System.Threading; |
37 | using log4net; | 38 | using log4net; |
38 | using Nini.Config; | 39 | using Nini.Config; |
@@ -413,11 +414,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
413 | } | 414 | } |
414 | } | 415 | } |
415 | 416 | ||
417 | private int nAsyncRequests = 0; | ||
416 | /// <summary> | 418 | /// <summary> |
417 | /// Processing thread main() loop for doing remote mapitem requests | 419 | /// Processing thread main() loop for doing remote mapitem requests |
418 | /// </summary> | 420 | /// </summary> |
419 | public void process() | 421 | public void process() |
420 | { | 422 | { |
423 | const int MAX_ASYNC_REQUESTS = 20; | ||
421 | try | 424 | try |
422 | { | 425 | { |
423 | while (true) | 426 | while (true) |
@@ -437,10 +440,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
437 | dorequest = false; | 440 | dorequest = false; |
438 | } | 441 | } |
439 | 442 | ||
440 | if (dorequest) | 443 | if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) |
441 | { | 444 | { |
442 | OSDMap response = RequestMapItemsAsync("", st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); | 445 | while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break |
443 | RequestMapItemsCompleted(response); | 446 | Thread.Sleep(80); |
447 | |||
448 | RequestMapItemsDelegate d = RequestMapItemsAsync; | ||
449 | d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null); | ||
450 | //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); | ||
451 | //RequestMapItemsCompleted(response); | ||
452 | Interlocked.Increment(ref nAsyncRequests); | ||
444 | } | 453 | } |
445 | } | 454 | } |
446 | 455 | ||
@@ -469,8 +478,18 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
469 | /// Sends the mapitem response to the IClientAPI | 478 | /// Sends the mapitem response to the IClientAPI |
470 | /// </summary> | 479 | /// </summary> |
471 | /// <param name="response">The OSDMap Response for the mapitem</param> | 480 | /// <param name="response">The OSDMap Response for the mapitem</param> |
472 | private void RequestMapItemsCompleted(OSDMap response) | 481 | private void RequestMapItemsCompleted(IAsyncResult iar) |
473 | { | 482 | { |
483 | AsyncResult result = (AsyncResult)iar; | ||
484 | RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate; | ||
485 | |||
486 | OSDMap response = (OSDMap)icon.EndInvoke(iar); | ||
487 | |||
488 | Interlocked.Decrement(ref nAsyncRequests); | ||
489 | |||
490 | if (!response.ContainsKey("requestID")) | ||
491 | return; | ||
492 | |||
474 | UUID requestID = response["requestID"].AsUUID(); | 493 | UUID requestID = response["requestID"].AsUUID(); |
475 | 494 | ||
476 | if (requestID != UUID.Zero) | 495 | if (requestID != UUID.Zero) |
@@ -538,6 +557,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
538 | EnqueueMapItemRequest(st); | 557 | EnqueueMapItemRequest(st); |
539 | } | 558 | } |
540 | 559 | ||
560 | private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags, | ||
561 | uint EstateID, bool godlike, uint itemtype, ulong regionhandle); | ||
541 | /// <summary> | 562 | /// <summary> |
542 | /// Does the actual remote mapitem request | 563 | /// Does the actual remote mapitem request |
543 | /// This should be called from an asynchronous thread | 564 | /// This should be called from an asynchronous thread |
@@ -552,9 +573,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
552 | /// <param name="itemtype">passed in from packet</param> | 573 | /// <param name="itemtype">passed in from packet</param> |
553 | /// <param name="regionhandle">Region we're looking up</param> | 574 | /// <param name="regionhandle">Region we're looking up</param> |
554 | /// <returns></returns> | 575 | /// <returns></returns> |
555 | private OSDMap RequestMapItemsAsync(string httpserver, UUID id, uint flags, | 576 | private OSDMap RequestMapItemsAsync(UUID id, uint flags, |
556 | uint EstateID, bool godlike, uint itemtype, ulong regionhandle) | 577 | uint EstateID, bool godlike, uint itemtype, ulong regionhandle) |
557 | { | 578 | { |
579 | string httpserver = ""; | ||
558 | bool blacklisted = false; | 580 | bool blacklisted = false; |
559 | lock (m_blacklistedregions) | 581 | lock (m_blacklistedregions) |
560 | { | 582 | { |
@@ -638,7 +660,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
638 | os = mapitemsrequest.GetRequestStream(); | 660 | os = mapitemsrequest.GetRequestStream(); |
639 | os.Write(buffer, 0, buffer.Length); //Send it | 661 | os.Write(buffer, 0, buffer.Length); //Send it |
640 | os.Close(); | 662 | os.Close(); |
641 | //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from Sim {0}", httpserver); | 663 | //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from {0}", httpserver); |
642 | } | 664 | } |
643 | catch (WebException ex) | 665 | catch (WebException ex) |
644 | { | 666 | { |
@@ -654,15 +676,22 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
654 | 676 | ||
655 | return responseMap; | 677 | return responseMap; |
656 | } | 678 | } |
679 | catch | ||
680 | { | ||
681 | m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); | ||
682 | responseMap["connect"] = OSD.FromBoolean(false); | ||
683 | return responseMap; | ||
684 | } | ||
657 | 685 | ||
658 | string response_mapItems_reply = null; | 686 | string response_mapItems_reply = null; |
659 | { // get the response | 687 | { // get the response |
688 | StreamReader sr = null; | ||
660 | try | 689 | try |
661 | { | 690 | { |
662 | WebResponse webResponse = mapitemsrequest.GetResponse(); | 691 | WebResponse webResponse = mapitemsrequest.GetResponse(); |
663 | if (webResponse != null) | 692 | if (webResponse != null) |
664 | { | 693 | { |
665 | StreamReader sr = new StreamReader(webResponse.GetResponseStream()); | 694 | sr = new StreamReader(webResponse.GetResponseStream()); |
666 | response_mapItems_reply = sr.ReadToEnd().Trim(); | 695 | response_mapItems_reply = sr.ReadToEnd().Trim(); |
667 | } | 696 | } |
668 | else | 697 | else |
@@ -683,6 +712,24 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
683 | 712 | ||
684 | return responseMap; | 713 | return responseMap; |
685 | } | 714 | } |
715 | catch | ||
716 | { | ||
717 | m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); | ||
718 | responseMap["connect"] = OSD.FromBoolean(false); | ||
719 | lock (m_blacklistedregions) | ||
720 | { | ||
721 | if (!m_blacklistedregions.ContainsKey(regionhandle)) | ||
722 | m_blacklistedregions.Add(regionhandle, Environment.TickCount); | ||
723 | } | ||
724 | |||
725 | return responseMap; | ||
726 | } | ||
727 | finally | ||
728 | { | ||
729 | if (sr != null) | ||
730 | sr.Close(); | ||
731 | } | ||
732 | |||
686 | OSD rezResponse = null; | 733 | OSD rezResponse = null; |
687 | try | 734 | try |
688 | { | 735 | { |
@@ -691,14 +738,29 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
691 | responseMap = (OSDMap)rezResponse; | 738 | responseMap = (OSDMap)rezResponse; |
692 | responseMap["requestID"] = OSD.FromUUID(requestID); | 739 | responseMap["requestID"] = OSD.FromUUID(requestID); |
693 | } | 740 | } |
694 | catch (Exception) | 741 | catch (Exception ex) |
695 | { | 742 | { |
696 | //m_log.InfoFormat("[OGP]: exception on parse of rez reply {0}", ex.Message); | 743 | m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); |
697 | responseMap["connect"] = OSD.FromBoolean(false); | 744 | responseMap["connect"] = OSD.FromBoolean(false); |
745 | lock (m_blacklistedregions) | ||
746 | { | ||
747 | if (!m_blacklistedregions.ContainsKey(regionhandle)) | ||
748 | m_blacklistedregions.Add(regionhandle, Environment.TickCount); | ||
749 | } | ||
698 | 750 | ||
699 | return responseMap; | 751 | return responseMap; |
700 | } | 752 | } |
701 | } | 753 | } |
754 | |||
755 | if (!responseMap.ContainsKey(itemtype.ToString())) // remote sim doesnt have the stated region handle | ||
756 | { | ||
757 | if (!m_blacklistedregions.ContainsKey(regionhandle)) | ||
758 | { | ||
759 | m_log.DebugFormat("[WORLD MAP]: Remote sim does not have the stated region. Blacklisting."); | ||
760 | m_blacklistedregions.Add(regionhandle, Environment.TickCount); | ||
761 | } | ||
762 | } | ||
763 | |||
702 | return responseMap; | 764 | return responseMap; |
703 | } | 765 | } |
704 | 766 | ||