示例#1
0
// Add or update a client's subscription to ringer state changes in the
// doubly-linked "subscriptions" list.
void subscribe_client(struct sockaddr_in* client) {
  struct subscription_node* subscription_node = find_subscription_node(client);
  if(subscription_node == NULL) { // This client is not already in the list.
    struct subscription_node* node = make_subscription_node(make_subscription(client));
    insert_subscription_node(node);
  } else { // The client is already in the list, update expiry time.
    struct timeval now;
    gettimeofday(&now, NULL);
    subscription_node->subscription.time = now.tv_sec;
  }
}
示例#2
0
            void subscribe_to(collection_type st)
            {
                auto state = this->shared_from_this();

                collectionLifetime = composite_subscription();

                // when the out observer is unsubscribed all the
                // inner subscriptions are unsubscribed as well
                auto innercstoken = state->out.add(collectionLifetime);

                collectionLifetime.add(make_subscription([state, innercstoken](){
                    state->out.remove(innercstoken);
                }));

                auto selectedSource = on_exception(
                    [&](){return state->coordinator.in(std::move(st));},
                    state->out);
                if (selectedSource.empty()) {
                    return;
                }

                // this subscribe does not share the out subscription
                // so that when it is unsubscribed the out will continue
                auto sinkInner = make_subscriber<value_type>(
                    state->out,
                    collectionLifetime,
                // on_next
                    [state, st](value_type ct) {
                        state->out.on_next(ct);
                    },
                // on_error
                    [state](std::exception_ptr e) {
                        state->out.on_error(e);
                    },
                //on_completed
                    [state](){
                        if (!state->selectedCollections.empty()) {
                            auto value = state->selectedCollections.front();
                            state->selectedCollections.pop_front();
                            state->collectionLifetime.unsubscribe();
                            state->subscribe_to(value);
                        } else if (!state->sourceLifetime.is_subscribed()) {
                            state->out.on_completed();
                        }
                    }
                );
                auto selectedSinkInner = on_exception(
                    [&](){return state->coordinator.out(sinkInner);},
                    state->out);
                if (selectedSinkInner.empty()) {
                    return;
                }
                selectedSource->subscribe(std::move(selectedSinkInner.get()));
            }
示例#3
0
/**
 * @brief Starts the KP, initializes state and cals all necessary functions.
 *
 * @return 0.
 */
int main()
{
    // Sets handler for CTR+C
    signal(SIGINT, &signal_callback_handler);

    // Initialize smart space information and data about subscription.
    ss_info_t info;
    subs_t subs;
        
    ss_init_space_info(&info, KP_SS_NAME, KP_SS_ADDRESS, KP_SS_PORT);
    
    subs.is_subscribed = false;
    subs.new_triples = NULL;
    subs.old_triples = NULL;
       
   // In the smart space the name of the KP must be unique, if you try to 
   // join without leave, then you received an error.
    if (ss_join(&info, KP_NAME) == -1) {
        printf("Can't join to SS.\n");
        return 0;
    }

    printf("KP join to SS.\n");
    
    // Create a subscription to <KP-says-*> triples.
    if (make_subscription(&info, &subs) != 0) {
        printf("Can't subscribe.\n");
        ss_leave(&info);    
        return 0;
    }
    
    printf("\nWaiting new data.\n");
    
    // Start subscription processing, it is ends:
    // - when yo press CTRL+C;
    // - when unsubscription indication will be received from the SS;
    // - on error.
    handle_subscription(&info, &subs);
    
    // Before leave we need to unsubscribe our subscription.
    handle_unsubscription(&info, &subs);
    
    // Delete triples list.
    update_subscription_triples(&subs, NULL, NULL);
    
    ss_leave(&info);    

    printf("\nKP leave SS...\n");

    return 0;
}
示例#4
0
    void on_connect(composite_subscription cs) {
        if (connection.empty()) {
            // the lifetime of each connect is independent
            auto destination = subject_value.get_subscriber();

            // when the paramter is unsubscribed it should
            // unsubscribe the most recent connection
            connection.reset(cs.add(destination.get_subscription()));

            // when the connection is finished it should shutdown the connection
            destination.add(make_subscription(
                [cs, this](){
                    cs.remove(this->connection.get());
                    this->connection.reset();
                }));

            source.subscribe(destination);
        }
    }
示例#5
0
    void on_subscribe(Subscriber scbr) const {
        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");

        typedef Subscriber output_type;

        struct merge_state_type
            : public std::enable_shared_from_this<merge_state_type>
            , public values
        {
            merge_state_type(values i, coordinator_type coor, output_type oarg)
                : values(i)
                , source(i.source_operator)
                , pendingCompletions(0)
                , coordinator(std::move(coor))
                , out(std::move(oarg))
            {
            }
            observable<source_value_type, source_operator_type> source;
            // on_completed on the output must wait until all the
            // subscriptions have received on_completed
            int pendingCompletions;
            coordinator_type coordinator;
            output_type out;
        };

        auto coordinator = initial.coordination.create_coordinator(scbr.get_subscription());

        // take a copy of the values for each subscription
        auto state = std::shared_ptr<merge_state_type>(new merge_state_type(initial, std::move(coordinator), std::move(scbr)));

        composite_subscription outercs;

        // when the out observer is unsubscribed all the
        // inner subscriptions are unsubscribed as well
        state->out.add(outercs);

        auto source = on_exception(
            [&](){return state->coordinator.in(state->source);},
            state->out);
        if (source.empty()) {
            return;
        }

        ++state->pendingCompletions;
        // this subscribe does not share the observer subscription
        // so that when it is unsubscribed the observer can be called
        // until the inner subscriptions have finished
        auto sink = make_subscriber<source_value_type>(
            state->out,
            outercs,
        // on_next
            [state](source_value_type st) {

                composite_subscription innercs;

                // when the out observer is unsubscribed all the
                // inner subscriptions are unsubscribed as well
                auto innercstoken = state->out.add(innercs);

                innercs.add(make_subscription([state, innercstoken](){
                    state->out.remove(innercstoken);
                }));

                auto selectedSource = on_exception(
                    [&](){return state->coordinator.in(st);},
                    state->out);
                if (selectedSource.empty()) {
                    return;
                }

                ++state->pendingCompletions;
                // this subscribe does not share the source subscription
                // so that when it is unsubscribed the source will continue
                auto sinkInner = make_subscriber<value_type>(
                    state->out,
                    innercs,
                // on_next
                    [state, st](value_type ct) {
                        state->out.on_next(std::move(ct));
                    },
                // on_error
                    [state](std::exception_ptr e) {
                        state->out.on_error(e);
                    },
                //on_completed
                    [state](){
                        if (--state->pendingCompletions == 0) {
                            state->out.on_completed();
                        }
                    }
                );
                auto selectedSinkInner = on_exception(
                    [&](){return state->coordinator.out(sinkInner);},
                    state->out);
                if (selectedSinkInner.empty()) {
                    return;
                }
                selectedSource->subscribe(std::move(selectedSinkInner.get()));
            },
        // on_error
            [state](std::exception_ptr e) {
                state->out.on_error(e);
            },
        // on_completed
            [state]() {
                if (--state->pendingCompletions == 0) {
                    state->out.on_completed();
                }
            }
        );
        auto selectedSink = on_exception(
            [&](){return state->coordinator.out(sink);},
            state->out);
        if (selectedSink.empty()) {
            return;
        }
        source->subscribe(std::move(selectedSink.get()));
    }