Home All Groups Group Topic Archive Search About

Using IPC question: one process as IPC client and server at same time problem.

Author
31 Jul 2006 1:09 PM
evgenyv
Hi!

Each machine is running couple of processes. Each process is using my
Cache object.
The question: how to notify "other" processes when cache of any process
became invalid? I mean to set communication between processes.

I've started to implemented IPC channel, but it couldn't be
implemented, because in my case each process should be client of all
others process and also should be a server for all other clients(other
processes) as well.

I've planned to run follow code on static constructor of Cache object,
But it doesn't work.
Error Message i got:
Attempt to redirect activation for type 'MyTest.CacheChangeNotifier,
MyTest.Cache'. This is not allowed since either a well-known service
type has already been registered with that type or that type has been
registered has a activated service type

I wan't to create each other exe separate notificatior class.
------------

static Cache()
{
                m_ProcessesNode =
(XmlNode)Settings.GetData("ExternalProcesses");
                RegisterServerChannelIPC();
                RegisterClientChannelsIPC();

}



private static void RegisterServerChannelIPC()
        {
            Hashtable properties = new Hashtable();

            BinaryServerFormatterSinkProvider serverProv = new
BinaryServerFormatterSinkProvider();

            serverProv.TypeFilterLevel =
System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
            string portName =
System.Diagnostics.Process.GetCurrentProcess().ProcessName;

            properties["portName"] = portName;
            properties["authorizedGroup"] = "Everyone";

            IpcServerChannel chan = new IpcServerChannel(properties,
serverProv);

            chan.StartListening(null);

            ChannelServices.RegisterChannel(chan, false);

            Assembly assemblyObject = Assembly.LoadFrom(m_InstallPath +
m_ProcessesNode.SelectSingleNode("assembly").InnerText);

            Type myType;

            myType =
assemblyObject.GetType("MyTest.CacheChangeNotifier");

RemotingConfiguration.RegisterWellKnownServiceType(
                            myType,
                            "Cache", WellKnownObjectMode.SingleCall);
        }

        private static void RegisterClientChannelsIPC()
        {
            XmlNodeList processesList =
m_ProcessesNode.SelectNodes("ExternalProcess");
            m_RemoteObjects = new List<CacheChangeNotifier>();

            foreach(XmlNode nodeProcess in processesList)
            {
                if(nodeProcess.InnerText !=
System.Diagnostics.Process.GetCurrentProcess().ProcessName)
                {
                    IpcClientChannel clientChannel = new
IpcClientChannel(nodeProcess.InnerText + "_Client", null);
                    clientChannel.IsSecured = false;

                    ChannelServices.RegisterChannel(clientChannel,
false);

                    Assembly assemblyObject =
Assembly.LoadFrom(m_InstallPath +
m_ProcessesNode.SelectSingleNode("assembly").InnerText);

                    Type myType;

                    myType =
assemblyObject.GetType("MyTest.CacheChangeNotifier");


RemotingConfiguration.RegisterWellKnownClientType(myType, "ipc://" +
nodeProcess.InnerText + @"/Cache");

                    CacheChangeNotifier item = new
CacheChangeNotifierClient();

                    m_RemoteObjects.Add(item);
                }
            }
        }

internal class CacheChangeNotifier : MarshalByRefObject
    {
        internal virtual void Clear_Notify(string cacheID)
        {
            Cache.GetCache(cacheID).Clear();
        }
    }

    internal class CacheChangeNotifierClient : CacheChangeNotifier
    {
    }

    internal class CacheChangeNotifierServer : CacheChangeNotifier
    {
    }



public ClearCache(string id)

{

            foreach(CacheChangeNotifier notifProxy in m_RemoteObjects)
            {
                try
                {
                    notifProxy.Clear_Notify(id);//it will run in remote
process
                }
                catch(Exception ex)
                {
                    EventLogger.WriteMessage("Cache proxy Clear_Notify(
) failed\n" + ex.Message);
                }
            }

}

------------

Error Message i got:
Attempt to redirect activation for type 'MyTest.CacheChangeNotifier,
MyTest.Cache'. This is not allowed since either a well-known service
type has already been registered with that type or that type has been
registered has a activated service type

Any suggestions?
Thanks in advance,

Evgeny

Author
31 Jul 2006 4:31 PM
Vadym Stetsyak
Hello, evge***@yahoo.com!

e> Each machine is running couple of processes. Each process is using my
e> Cache object.
e> The question: how to notify "other" processes when cache of any process
e> became invalid? I mean to set communication between processes.

e> I've started to implemented IPC channel, but it couldn't be
e> implemented, because in my case each process should be client of all
e> others process and also should be a server for all other clients(other
e> processes) as well.

If these processes are on the one machine, then you can:
- use some global ( named ) sync primitive and check its status from every process
- use windows messages
- memory-mapped file

in case when on the different machines, then
- use udp multicasting, to notify about cache invalidation
- build tcp p2p like network ( overkill ) or put cache managed on separate server.
--
Regards, Vadym Stetsyak
www: http://vadmyst.blogspot.com

AddThis Social Bookmark Button