[.NET/C#] Singleton patern, gedistribueerd?

Pagina: 1
Acties:

  • Scare360
  • Registratie: Juli 2001
  • Laatst online: 27-08 08:10
Damn lastige... Ik heb 1 DLL en 2 clients waarvan in een later stadium zowel de clients als de assemblie over losse machines verdeeld worden.

client 1
code:
1
2
3
4
5
6
7
8
        private Singleton.Singleton sSingleton1;
        private Singleton.Singleton sSingleton2;
            sSingleton1 = Singleton.Singleton.Instance();
            sSingleton2 = Singleton.Singleton.Instance();
            sSingleton1.Stock = 10;
            sSingleton2.Stock = 5;
            this.label1.Text = sSingleton1.Stock.ToString();
            this.label2.Text = sSingleton2.Stock.ToString();

client2
code:
1
2
3
        private Singleton.Singleton sSingleton;
        sSingleton = Singleton.Singleton.Instance();
            sSingleton.Stock = 20;

assemblie
code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;

namespace Singleton
{
    /// <summary>
    /// Summary description for Singleton.
    /// </summary>
    public class Singleton
    {
        private static Singleton instance;
        private int _stock;

        protected Singleton() {}

        public static Singleton Instance()
        {
            if (instance  == null)
            {
                instance = new Singleton();
            };
            return instance;
        }

        public void UpdateStock(int intStock)
        {
            _stock = intStock;
        }

        public int Stock
        {
            get
            {
                return _stock;
            }
            set
            {
                _stock = value;
            }
        }
    }
}

Nu wil ik dat zowel client1 als client2 een referentie hebben op de assemblie zodat als ik bij client1 de stock op 10 zet deze ook voor client2 op 10 komt te staan. Probleem is dat nu nadat ik bij client1 stock op 5 zet en nadien op 10 netjes bij labels 10 weergeven wat het bewijs is dat de singleton werkt in 1 .exe, maar hoe kan ik nu client2 op dezelfde referentie de assemblie laten benaderen zodat die ook de stock waarde van 10 in zijn labeltje krijgt.

Als dat niet netjes simpel uitgelegd is dan weet ik het ook niet meer

Mijn bedoeling hiermee is om ltr meerdere client middel singleton en een model view controller op de business logica te hangen en automatische updates op de views te doen...tevens moet het model gezien het systeem contaminatie bewaking heeft netjes alles op 1 object uitgevoerd wordt... maar als dit simpele testproject nog niet wil :(

Verwijderd

Klassiek probleem: waar beware men de 'state' van een applicatie. Indien je distributed bezig bent, ontkom je niet aan een stateless model waarbij je de state bewaart in een database, danwel in een verzameling objects op een centrale machine waar de distributed applicatie contact mee maakt.

Een referentie naar een assembly is puur waar de code staat, maar niet waar de instance van objects draaien. Die draaien in het process van de client die de objects aanroept, TENZIJ je 1 centraal object aanmaakt op een server en daar verbinding mee maakt via remoting.

In core state management is wel nadelig: als je process crasht of je bak, ben je je state kwijt en kun je die niet meer terughalen.

  • Scare360
  • Registratie: Juli 2001
  • Laatst online: 27-08 08:10
Dit moet toch gewoon gaan via COM...tis niets meer dan pointertjes hevelen. Jah ik weet als de Business plat gaat alle clients ook meteen opnieuw opgestart moeten worden, maar tis toch te gek dat dit in .NET niet werkt.

Dit werkt zelfs niet op dezelfde machine! Retevaag aangezien Java wel gewoon 2 clients op 1 Assembly kan laten draaien terwijl ze beide dezelfde unieke instantie aanspreken.

Argh

Verwijderd

Het is niet de assembly. Daar staat in wat de code is, maar niet de instances. Dus je kunt 10 clients allemaal naar dezelfde assembly laten wijzen, als die clients allemaal een instance creeeren van dezelfde class heb je 10 objects en niet 1.

Dit is klassiek client server :) 1 server met daarin de data en meerdere clients die verbinding hebben met die server voor de data. Wat je zou kunnen doen is een 'server' applicatie te maken waar je singleton object in zit, en je clients via remoting verbinding te laten maken met dat server process voor de data. Het is anders semantisch niet correct, want waar IS de data gelocaliseerd? dat kan alleen op een centrale plek.

Is het niet zo dat per opgestarte .net applicatie er een CLR process wordt gestart?

  • Scare360
  • Registratie: Juli 2001
  • Laatst online: 27-08 08:10
Op maandag 06 mei 2002 17:26 schreef Otis het volgende:
Het is niet de assembly. Daar staat in wat de code is, maar niet de instances. Dus je kunt 10 clients allemaal naar dezelfde assembly laten wijzen, als die clients allemaal een instance creeeren van dezelfde class heb je 10 objects en niet 1.

Dit is klassiek client server :) 1 server met daarin de data en meerdere clients die verbinding hebben met die server voor de data. Wat je zou kunnen doen is een 'server' applicatie te maken waar je singleton object in zit, en je clients via remoting verbinding te laten maken met dat server process voor de data. Het is anders semantisch niet correct, want waar IS de data gelocaliseerd? dat kan alleen op een centrale plek.

Is het niet zo dat per opgestarte .net applicatie er een CLR process wordt gestart?
Tis toch te gek dat je niet meerdere views op je object kan maken... how the hell wil je anders je Business logica fatsoenlijk invullen?

Verwijderd

Ik begrijp niet echt waar je nu op doelt. views op een object lijken me niet een concept dat je zou willen, views op DATA wel. Maar dan praat je over een 'state' die ergens wordt bewaard. Dat gebeurt niet zomaar, daar moet je wel wat voor doen! (tm) :). Binnen win32 development zul je ook via inter-process communicatie data moeten uitwisselen, dat gaat ook niet vanzelf.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 06-09 22:39
Op maandag 06 mei 2002 23:27 schreef Otis het volgende:
Ik begrijp niet echt waar je nu op doelt. views op een object lijken me niet een concept dat je zou willen, views op DATA wel.
Is het niet een redelijke gangbare methode om je data ook in een object onder te brengen?

Verder vraag ik me af wat mensen nou precies bedoelen met assembly in de context van .net. Is dit alleen maar om de verwarring te vergroten?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Op dinsdag 07 mei 2002 09:04 schreef farlane het volgende:
[..]
Is het niet een redelijke gangbare methode om je data ook in een object onder te brengen?
Jawel, maar dat object moet ook ergens leven :)
Verder vraag ik me af wat mensen nou precies bedoelen met assembly in de context van .net. Is dit alleen maar om de verwarring te vergroten?
Een assembly is een unit met daarin classes en datafiles die bijelkaar horen. Te vergelijken met een DLL met daarin code en resources.

Verwijderd

Paulgielens: hoe maak je nu nieuwe instances aan? Via .Net remoting, of op een andere manier?

Want zoals Otis al aangeeft lijkt me dat ook de enige manier om dit voor elkaar te brengen... Zoals je het nu lijkt het me idd dat je proces in twee processen wordt gerund. In klassieke COM kon je dat volgens mij deels voorkomen (een VB ActiveX dll draaide altijd in één proces per pc, en een ActiveX exe draaide in één proces per instance)

  • Scare360
  • Registratie: Juli 2001
  • Laatst online: 27-08 08:10
Op dinsdag 07 mei 2002 10:04 schreef KoenM het volgende:
Paulgielens: hoe maak je nu nieuwe instances aan? Via .Net remoting, of op een andere manier?

Want zoals Otis al aangeeft lijkt me dat ook de enige manier om dit voor elkaar te brengen... Zoals je het nu lijkt het me idd dat je proces in twee processen wordt gerund. In klassieke COM kon je dat volgens mij deels voorkomen (een VB ActiveX dll draaide altijd in één proces per pc, en een ActiveX exe draaide in één proces per instance)
Correct de .NET equivalent is Remoting waarmee je in de web.config aan kunt geven of deze SingleCall of Singleton moet zijn. Je communiceerd dan middels channels oftewel... bah. Ben nu met wat implementatie aan het knoeien, maar dat ik nu zeg dat dat lekker gaat, nee

Verwijderd

Maar, heb je dan niet een class factory nodig die instances poolt ipv een singleton ? Want, singleton, houdt dat in: 1 instance per doos, per netwerk of per proces ? Ik krijg het vermoeden per proces.

'web.config' zegt me dat je een webservice gebruikt? Die zijn stateless.

Verwijderd

Ik heb hier een prachtig boek 'C# Web Services' van Wrox voor m'n neus leggen en citeer de volgende code:
code:
1
2
3
4
5
6
7
8
9
10
public class PizzaDeliveryService : MarshalByRefObject
{
  public event //...
  public static PizzaDeliveryService singleton = nulll
  public PizzaDeliveryService()
  {
    singleton = this;
  }

}

Dan moet in je .config file wel Singleton als mode staan. Dat MarshalByRefObject is ook zeer belangrijk. Ben je dat niet vergeten?

/Edit:
Op dinsdag 07 mei 2002 10:25 schreef Otis het volgende:
'web.config' zegt me dat je een webservice gebruikt? Die zijn stateless.
Bij .Net remoting moet je ook van een .config file gebruik maken, en die kunnen wel state hebben, als je ze maar als Singleton en niet als SingleCall definieerd :).

Verwijderd

is dat niet app.config? :)

Btw: als je op client 1 een object aan maakt dat ook door client 2 wordt gebruikt, moet je dan niet voor beide clients verschillende code maken? (client 1 gebruikt het object lokaal, en client 2 moet een reference leggen naar een ander proces).

  • Scare360
  • Registratie: Juli 2001
  • Laatst online: 27-08 08:10
Nee luister ik heb een stukje Business logica in een assemblie oftewel DLL gepleurt. Deze is MarshalByRefObject en bevat als root een klasse welke singleton is. Als ik daartegen 2 clients maak dan maken beide clients een instantie aan ongeacht ik singleton gebruik ja dan nee. Dit is wellicht te verklaren omdat beide applicaties de DLL binnen hun proces laden.

Business met stock voorraad
code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;

namespace Singleton
{
    /// <summary>
    /// Summary description for Singleton.
    /// </summary>
    public class Singleton : MarshalByRefObject
    {
        private static Singleton instance;
        private int _stock;

        protected Singleton() {}

        public static Singleton Instance()
        {
            if (instance  == null)
            {
                instance = new Singleton();
            };
            return instance;
        }

        public void UpdateStock(int intStock)
        {
            _stock = intStock;
        }

        public int Stock
        {
            get
            {
                return _stock;
            }
            set
            {
                _stock = value;
            }
        }
    }
}

Zie de clients bovenstaand... de ene client instantieert de singleton en zet de stock op 5. Als ik dan de tweede client start maakt die ook gewoon een nieuwe instantie en geeft als stockwaarde 0 weer. Als ik met de debugger step is ook duidelijk te zien dat er voor beide clients een instantie gemaakt wordt... ondertussen heb ik het wel middels een Channel/Remoting voor mekaar gekregen... maar de combinatie client1.exe, client2.exe en singleton.dll werkt dus tot nu toe niet. Iemand een idee of dit uberhaupt wel mogelijk is?

Verwijderd

precies: 2 objects ipv 1.
Hoe dat is op te lossen is door een 3e process te starten mer daarin je object en daarmee een link te leggen vanuit je client code.

  • Scare360
  • Registratie: Juli 2001
  • Laatst online: 27-08 08:10
Op dinsdag 07 mei 2002 12:16 schreef Otis het volgende:
precies: 2 objects ipv 1.
Hoe dat is op te lossen is door een 3e process te starten mer daarin je object en daarmee een link te leggen vanuit je client code.
en hoe doe je dat dan volgens jouw in .NET "the right way"?

Verwijderd

Op dinsdag 07 mei 2002 13:05 schreef paulgielens het volgende:

[..]

en hoe doe je dat dan volgens jouw in .NET "the right way"?
Ik zou het middels een service doen die uit meerdere threads bestaat: 1 thread die de object store behandelt (dus een verzameling live objects in core) en een thread die connections afhandelt. Als client maak je verbinding met die service, vraagt een object op en dat wordt dan door de service OF uit de object store gehaald of gecreeerd wanneer deze er niet is.

Deze server implementeert een interface voor je object en registreert een 'well known object', middels RemotingConfiguration.RegisterWellKnownServiceType(). De server registreert ook een channel.

De sourcecode voor de remoting calculator example van dit boek: http://www.libertyassociates.com/pages/Books.htm (Programming C#) is een mooi voorbeeld.

De client maakt verbinding via het bekende channel, vraagt een object van het type van de interface van je object en gaat daarmee aan de slag.

  • Scare360
  • Registratie: Juli 2001
  • Laatst online: 27-08 08:10
Ik heb een dergelijk systeem nu geimplementeerd, ik kan middels Singleton zonder problemen meerdere clients aan dezelfde referentie hangen, ook remote alleen indien ik dan tracht een model view controller in te bouwen gaat alles op zijn gat...je bent dan de referentie kwijt Arg...om gek van te worden

Verwijderd

Wat is een model view controller?

  • Scare360
  • Registratie: Juli 2001
  • Laatst online: 27-08 08:10
zodat je meerdere client op een business object kan hangen. Indien je bv een propertie veranderd wordt een event opgegooid en doorgespeeld naar alle clients. Deze voeren dan een update uit zodat de interface een refresh krijgt. Is overigens ook in de MSDN te vinden.

  • Scare360
  • Registratie: Juli 2001
  • Laatst online: 27-08 08:10
Ik heb ook de view controller aan de gang gekregen maar helaas werkt het weer eens niet. Als ik dus Remoting gebruik gebruik het TCP/IP gebeuren. zodra ik een event krijg begint de client te zeuren dat het betreffende TCP/IP kanaal al in gebruik is ARGH.

Dat MS eens fatsoenlijke voorbeelden maakt ipv die webenabled ASP shit

Verwijderd

Op woensdag 08 mei 2002 08:50 schreef paulgielens het volgende:
Dat MS eens fatsoenlijke voorbeelden maakt ipv die webenabled ASP shit
Heb je al eens een goed boek over .Net remoting geprobeerd? Zoals ik al eerder aangaf ben ik er nu eentje van Wrox aan het lezen (helft is ASP.Net, andere helft .Net remoting) en ik moet zeggen dat dat zeer interresant is :).
In een boek staan meestal kant en klare voorbeeld applicaties die zeer leerzaam zijn.

  • Scare360
  • Registratie: Juli 2001
  • Laatst online: 27-08 08:10
Op woensdag 08 mei 2002 19:00 schreef KoenM het volgende:

[..]

Heb je al eens een goed boek over .Net remoting geprobeerd? Zoals ik al eerder aangaf ben ik er nu eentje van Wrox aan het lezen (helft is ASP.Net, andere helft .Net remoting) en ik moet zeggen dat dat zeer interresant is :).
In een boek staan meestal kant en klare voorbeeld applicaties die zeer leerzaam zijn.
heb je een ISBN voor me?

Ik heb nu een leuk stukje code klaar featuring,
-load ballancing
-mvc local/global
-remoting (TCP/IP)

client->business (load ballanced)->dataacces

de business logica kan ik starten op een nieuwe server en dan alle client overhevelen naar de nieuwe server, zodat ik onderhoud kan verrichten aan de "oude" server. Dit was de doelsteling van het ontwerp dus ja...redelijk. Probleem was het inbouwen van een degelijk event systeem. Toch is remoting niet zo makkelijk...

MS is niet echt duidelijk in de documentatie of remoting nu echt de vervanger gaat worden voor COM?

Verwijderd

vervanging van DCOM. .NET is de vervanger voor COM. COM is niets anders dan binary object model, dat niet meer nodig is in .NET, want je hebt daar de meta info per class in de assembly zitten.

Je app klinkt goed! een toepassing waar je niet 1 2 3 aan denkt maar waar je wel veel profijt van kan hebben.

Die loadbalancing heb je geregeld middels application server?

  • Scare360
  • Registratie: Juli 2001
  • Laatst online: 27-08 08:10
Op vrijdag 10 mei 2002 10:00 schreef Otis het volgende:
vervanging van DCOM. .NET is de vervanger voor COM. COM is niets anders dan binary object model, dat niet meer nodig is in .NET, want je hebt daar de meta info per class in de assembly zitten.

Je app klinkt goed! een toepassing waar je niet 1 2 3 aan denkt maar waar je wel veel profijt van kan hebben.

Die loadbalancing heb je geregeld middels application server?
Nee ik heb middels remoting de Business aan de Presentation gehangen. HTTP wel te verstaan. De Business->DataAccess ook middels remoting alleen dna via TCP/IP communicatie. Zo kan ik de GUI los trekken van het netwerk waar de zaak in gedistribueerd word. Wat ik gedaan heb is de DataAcces singleton gehouden. De business logica kan ik runtime verdelen. Ik stel gewoon de max remote clients in op de Business laag...zodra deze te groot wordt worden alle clients naar een andere Business logica server gestuurd. Ik kan tevens de gehele server ofline halen door een nieuwe BusinessLogica server op te starten en alle client over te hevelen naar de nieuwe server. Werkt perfect alleen moet je niet vergeten een queing systeem in te bouwen voor method calls. Bij het schakelen van server "kan" het zijn dat er calls onderweg zijn. Het event systeem werkt trouwens ook perfect in .NET. Op "The Code Project" staat een goede load ballanced chat demo. Zeker de moeite waard om eens aan te zien.
Pagina: 1