[.NET] Remoted object doet niets

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 07:01

GrimaceODespair

eens een tettenman, altijd ...

Topicstarter
Ik maak in .NET een AppDomain aan waarin ik een applicatie wil hosten:
C#:
1
2
3
AppDomain appDomain = AppDomain.CreateDomain(...);

MyApp myApp = (MyApp)appDomain.CreateInstanceAndUnwrap(...);


Nu wil ik een future-constructie opzetten om daar methodes op aan te roepen:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/********************************************************
* Afgeleide van RealProxy
********************************************************/
public class FutureProxy : RealProxy
{
  public MyApp _myApp;
  public IMessage _futureReturnMessage;

  // Onthoud de originele proxy van het object
  public FutureProxy(MyApp myApp)
  {
    _myApp = myApp;
  }

  // Onderschep alle berichten, en schedule ze via de thread pool.
  // Geef als return-waard een lege message terug
  public override IMessage Invoke(IMessage message)
  {
    ThreadPool.QueueUserWorkItem(delegate
    {
      _futureReturnMessage = RemotingServices.GetRealProxy(_myApp).Invoke(message);
    });

    return new ReturnMessage(/* fake empty message */);
  }
}


Bovenstaand code compileert en geeft geen runtime fouten. Alleen wordt de remote method call nooit uitgevoerd. Als ik de IMessage niet schedule, maar onmiddellijk uitvoer (met een call identiek hetzelfde als nu: GetRealProxy + Invoke), dan is het geen probleem.

Ik vermoed dat de scheiding van AppDomains hier voor iets tussenzit, maar hoe ik het precies kan oplossen, weet ik eigenlijk niet.

Iemand een idee?

Wij onderbreken deze thread voor reclame:
http://kalders.be


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 26-09 17:09
Wat bedoel je precies met het 'schedulen' van je call ?
Bedoel je dat je een probleem hebt als je die call op een andere thread wilt uitvoeren ?

Zoja: dan kan het een security probleem zijn. Onder welke credentials wordt die thread uitgevoerd ?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 07:01

GrimaceODespair

eens een tettenman, altijd ...

Topicstarter
Ik noem het schedulen, maar ik bedoel gewoon die QueueUserWorkItem-aanroep. Ik vermoed dat daar ook dingen gebeuren waar ik te weinig van weet (Threading en Remoting zijn niet mijn sterkste punten).

Credentials zouden overal gelijk moeten zijn.

Wij onderbreken deze thread voor reclame:
http://kalders.be


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 26-09 17:09
GrimaceODespair schreef op dinsdag 12 februari 2008 @ 09:43:
Credentials zouden overal gelijk moeten zijn.
Ben je dat zeker ? (Aannames zijn fataal)

Doe eens een
code:
1
Console.WriteLine (System.Threading.Thread.CurrentPrincipal.Identity.Name);

binnen de method die op die andere thread uitgevoerd wordt.

Indien het idd niet de gewenste user is (wat ik vermoed), dan kan je mbhv SetPrincipalPolicy specifieren welke 'policy' er moet gebruikt worden bij het attachen van een principal aan een thread die binnen het appdomain gestart wordt.

Heb je anders ook al eens een try catch rond die Invoke gezet, en gekeken welke exceptie er precies gegooid wordt ?
(Als er een exceptie in een andere thread gegooit wordt, heb je ook kans dat je deze anders nooit zult zien).

[ Voor 39% gewijzigd door whoami op 12-02-2008 09:59 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Je maakt een nieuwe application domain aan en deze neemt niet staandard de settings over van AppDomain.CurrentDomain. Het is niets meer dan een lege sandbox. Via AppDomainSetup kun je het nieuwe domein configureren.

Daarnaast betwijfel ik of futureReturnMessage een nuttige waarde treug zal krijgen. Een background thread hoeft namelijk niet direct te worden uitgevoerd en als je meerdere keren Invoke zou aanroepen dan staat de volgorde waarin de threads worden uitgevoerd niet vast. Ik ben bijna zeker dat je dit via een IAsyncResult implementatie zal moet afvangen.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 07:01

GrimaceODespair

eens een tettenman, altijd ...

Topicstarter
Ik hou al jullie nuttige opmerkingen nog even in beraad.

Ondertussen ben ik erachter dat de remoting call kwam niet doorkwam omdat de ReturnMessage constructor de request message aanpast. Op het moment dat hij checkt of het ding argumenten heeft, wordt er ook en passant een vlag gezet. Het is net die vlag die door de remoting infrastructure getest wordt om de call bv Synchronous uit te voeren. Na de aanpassing doet de infrastructure er niets meer mee.

Daarom heb ik dit
C#:
1
return new ReturnMessage(returnValue, new object[] { }, 0, null, requestMessage);


veranderd in dit:
C#:
1
return new ReturnMessage(returnValue, new object[] { }, 0, null, null);



Ik besef dat potentieel behoorlijk goor bezig ben, maar het idee was: gewoon je message delayen en er asynchroon op wachten, moet toch wel kunnen? :)

Een oplossing met remote Async-aanroepen lijkt daar misschien een logischer keuze, maar ik was mijn future aan het bouwen op basis van die van Ayende, en had een verhaal opgezet dat volledig analoog (niet) werkt met remoting proxies.

Update:
Ik heb het aan de gang. Volgens mij zit er een bug in het framework, maar mogelijk misbruik ik de remoting infrastructuur gewoon gruwelijk :) De messaging liep stuk op een corrupte message. Om dat te fixen, ziet de code er nu zo uit (met dank aan deze eenzame ziel met hetzelfde probleem):
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  public override IMessage Invoke(IMessage message) 
  {
    // Stel de argumenten veilig voor de threadwissel. De Args-aanroep
    // zal namelijk crashen wanneer hij uitgevoerd wordt in QueueUserWorkItem
    object[] args = (object[])message.Args.Clone();

    ThreadPool.QueueUserWorkItem(delegate 
    {
      // Lanceer een nieuwe invocation met de nieuwe argumenten
      _futureReturnMessage = RemotingServices
        .GetMethodBaseFromMethodMessage(message)
        .Invoke(_myApp, args); 
    }); 

    return new ReturnMessage(/* fake empty message */); 
  } 

[ Voor 30% gewijzigd door GrimaceODespair op 12-02-2008 14:28 ]

Wij onderbreken deze thread voor reclame:
http://kalders.be

Pagina: 1