Archived

This forum has been archived. Please start a new discussion on GitHub.

Async Subscriber

Is there a way to create an Async Subscriber with IceStorm?

Both the clock demo, and the documentation only demonstrate the blocking method communicator()->waitForShutdown();

Thanks,
Pete

Comments

  • mes
    mes California
    Hi Peter,

    An Ice application is not required to call waitForShutdown, it is simply a convenient way of blocking the calling thread until shutdown is invoked on the communicator. In a server context (such as an IceStorm subscriber), you only need to activate the object adapter to allow incoming requests to be dispatched.

    Hope that helps,
    Mark
  • It seems if I don't call that method it just seems like the subscriber closes right away:
    [ 03/03/08 18:36:15.515 Subscriber: 97ec16db-daba-49ef-943e-18e53d850782: topic publish failed: Network.cpp:664: Ice::ConnectionRefusedException:connection refused: WSAECONNREFUSED ]
    

    What I'm trying to do is just create a subscriber class, so I can just instantiate a subscriber object in my app:
    public class Subscriber : Ice.Application
        {
            private IceStorm.TopicPrx topic;
            private Ice.ObjectAdapter adapter;
            private Ice.ObjectPrx subscriber;
            private IceStorm.QoS qos;
    
            public class LimehouseI : LimehouseDisp_
            {
                public override void sendCommand(string date, Ice.Current current)
                {
                    System.Console.Out.WriteLine(date);
                }
            }
    
    
            public override int run(string[] args)
            {
                IceStorm.TopicManagerPrx manager = IceStorm.TopicManagerPrxHelper.checkedCast(
                    communicator().propertyToProxy("IceStorm.TopicManager.Proxy"));
                if (manager == null)
                {
                    Console.WriteLine("invalid proxy");
                    return 1;
                }
    
                string topicName = "LimehouseCMD";
                bool datagram = false;
                bool twoway = false;
                bool ordered = false;
                bool batch = false;
                int optsSet = 0;
                for (int i = 0; i < args.Length; ++i)
                {
                    if (args[i].Equals("--datagram"))
                    {
                        datagram = true;
                        ++optsSet;
                    }
                    else if (args[i].Equals("--twoway"))
                    {
                        twoway = true;
                        ++optsSet;
                    }
                    else if (args[i].Equals("--ordered"))
                    {
                        ordered = true;
                        ++optsSet;
                    }
                    else if (args[i].Equals("--oneway"))
                    {
                        ++optsSet;
                    }
                    else if (args[i].Equals("--batch"))
                    {
                        batch = true;
                    }
                    else if (args[i].StartsWith("--"))
                    {
                        usage();
                        return 1;
                    }
                    else
                    {
                        topicName = args[i];
                        break;
                    }
                }
    
                if (batch && (twoway || ordered))
                {
                    Console.WriteLine(appName() + ": batch can only be set with oneway or datagram");
                    return 1;
                }
    
                if (optsSet > 1)
                {
                    usage();
                    return 1;
                }
    
                //
                // Retrieve the topic.
                //
                
                try
                {
                    topic = manager.retrieve(topicName);
                }
                catch (IceStorm.NoSuchTopic)
                {
                    try
                    {
                        topic = manager.create(topicName);
                    }
                    catch (IceStorm.TopicExists)
                    {
                        Console.WriteLine("temporary error. try again.");
                        return 1;
                    }
                }
    
                adapter = communicator().createObjectAdapter("Limehouse.Subscriber");
    
                //
                // Add a Servant for the Ice Object.
                //
                subscriber = adapter.addWithUUID(new LimehouseI());
    
                qos = new IceStorm.QoS();
    
                //
                // Set up the proxy.
                //
                if (datagram)
                {
                    subscriber = subscriber.ice_datagram();
                }
                else if (twoway)
                {
                    // Do nothing to the subscriber proxy. Its already twoway.
                }
                else if (ordered)
                {
                    // Do nothing to the subscriber proxy. Its already twoway.
                    qos["reliability"] = "ordered";
                }
                else // if(oneway)
                {
                    subscriber = subscriber.ice_oneway();
                }
                if (batch)
                {
                    if (datagram)
                    {
                        subscriber = subscriber.ice_batchDatagram();
                    }
                    else
                    {
                        subscriber = subscriber.ice_batchOneway();
                    }
                }
    
                topic.subscribeAndGetPublisher(qos, subscriber);
                adapter.activate();
    
                //shutdownOnInterrupt();
                //communicator().waitForShutdown();
    
                //
                // Unsubscribe all subscribed objects.
                //
                //topic.unsubscribe(subscriber);
    
                return 0;
            }
    
            public void unsubscribe()
            {
                topic.unsubscribe(subscriber);
            }
    
            public void usage()
            {
                Console.WriteLine("Usage: " + appName() + " [--batch] [--datagram|--twoway|--ordered|--oneway] [topic]");
            }
    
        }
    

    It is the Clock demo. I just changed a few things here and there. Am I going about this incorrectly?

    Thanks,
    Pete
  • mes
    mes California
    Hi Pete,

    If your main thread has nothing else to do, you should call waitForShutdown to prevent the subscriber from exiting immediately.

    Take care,
    Mark
  • My main thread is running a GUI, so the app is still running when I receive that message. If I was to call that method, my GUI would never get drawn.

    Is it correct for the Subscriber to inherit from Ice.Application? This app also contains a Publisher class which also inherits from Ice.Application.

    Thanks,
    Pete
  • matthew
    matthew NL, Canada
    My main thread is running a GUI, so the app is still running when I receive that message. If I was to call that method, my GUI would never get drawn.

    Sorry, but what is your question here? If you don't want to block the caller until shutdown is called then don't call waitForShutdown.
    Is it correct for the Subscriber to inherit from Ice.Application? This app also contains a Publisher class which also inherits from Ice.Application.

    I'm afraid I don't understand this question either. Ice.Application is only a convenience class and you certainly don't have to use it. If it doesn't do what you want then you don't have to use it. I suggest you take a look in the Ice manual for more information on what Ice::Application is, and what it does for you (section 8.3.1 covers this). For an example of a bare bones Ice application take a look at demo/Ice/minimal.
  • matthew wrote: »
    Sorry, but what is your question here? If you don't want to block the caller until shutdown is called then don't call waitForShutdown.

    No question here, I was merely responding to Mark.
    matthew wrote: »
    I'm afraid I don't understand this question either. Ice.Application is only a convenience class and you certainly don't have to use it. If it doesn't do what you want then you don't have to use it. I suggest you take a look in the Ice manual for more information on what Ice::Application is, and what it does for you (section 8.3.1 covers this). For an example of a bare bones Ice application take a look at demo/Ice/minimal.

    Thanks, you cleared up my confusion.