| #-- |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| #++ |
| |
| module Qpid::Proton |
| |
| # The base for both Sender and Receiver, providing common functionality |
| # between both ends. |
| # |
| # A Link has a single parent Qpid::Proton::Session instance. |
| # |
| class Link < Endpoint |
| |
| # The sender will send all deliveries initially unsettled. |
| SND_UNSETTLED = Cproton::PN_SND_UNSETTLED |
| # The sender will send all deliveries settled to the receiver. |
| SND_SETTLED = Cproton::PN_SND_SETTLED |
| # The sender may send a mixture of settled and unsettled deliveries. |
| SND_MIXED = Cproton::PN_SND_MIXED |
| |
| # The receiver will settle deliveries regardless of what the sender does. |
| RCV_FIRST = Cproton::PN_RCV_FIRST |
| # The receiver will only settle deliveries after the sender settles. |
| RCV_SECOND = Cproton::PN_RCV_SECOND |
| |
| # @private |
| include Util::SwigHelper |
| |
| # @private |
| PROTON_METHOD_PREFIX = "pn_link" |
| |
| # @!attribute [r] state |
| # |
| # Returns the endpoint state flags. |
| # |
| proton_caller :state |
| |
| # @!method open |
| # |
| # Opens the link. Once this operation has completed, the state flag will be |
| # set. |
| # |
| # @see Endpoint::LOCAL_ACTIVE |
| proton_caller :open |
| |
| # @!method close |
| # |
| # Closes the link. |
| # |
| # Once this operation has completed, the state flag will be set. |
| # This may be called without first calling #open, which is the equivalent to |
| # calling #open and then #close. |
| # |
| # @see Endpoint::LOCAL_CLOSED |
| proton_caller :close |
| |
| # @!method detach |
| # |
| # Detaches the link. |
| proton_caller :detach |
| |
| # Advance the current delivery to the next on the link. |
| # |
| # For sending links, this operation is used to finish sending message data |
| # for the current outgoing delivery and move on to the next outgoing |
| # delivery (if any). |
| # |
| # For receiving links, this operatoin is used to finish accessing message |
| # data from the current incoming delivery and move on to the next incoming |
| # delivery (if any). |
| # |
| # @return [Boolean] True if the current delivery was changed. |
| # |
| # @see #current |
| # |
| proton_caller :advance |
| |
| proton_caller :unsettled |
| |
| # @!attribute [r] credit |
| # |
| # Returns the credit balance for a link. |
| # |
| # Links use a credit based flow control scheme. Every receiver maintains a |
| # credit balance that corresponds to the number of deliveries that the |
| # receiver can accept at any given moment. |
| # |
| # As more capacity becomes available at the receiver, it adds credit to this |
| # balance and communicates the new balance to the sender. Whenever a |
| # delivery is sent/received, the credit balance maintained by the link is |
| # decremented by one. |
| # |
| # Once the credit balance at the sender reaches zero, the sender must pause |
| # sending until more credit is obtained from the receiver. |
| # |
| # NOte that a sending link may still be used to send deliveries eve if |
| # credit reaches zero. However those deliveries will end up being buffer by |
| # the link until enough credit is obtained from the receiver to send them |
| # over the wire. In this case the balance reported will go negative. |
| # |
| # @return [Fixnum] The credit balance. |
| # |
| # @see #flow |
| # |
| proton_caller :credit |
| |
| # @!attribute [r] remote_credit |
| # |
| # Returns the remote view of the credit. |
| # |
| # The remote view of the credit for a link differs from the local view of |
| # credit for a link by the number of queued deliveries. In other words, |
| # remote credit is defined as credit - queued. |
| # |
| # @see #queued |
| # @see #credit |
| # |
| # @return [Fixnum] The remove view of the credit. |
| # |
| proton_caller :remote_credit |
| |
| # @!attribute [r] available |
| # |
| # Returns the available deliveries hint for a link. |
| # |
| # The available count for a link provides a hint as to the number of |
| # deliveries that might be able to be sent if sufficient credit were issued |
| # by the receiving link endpoint. |
| # |
| # @return [Fixnum] The available deliveries hint. |
| # |
| # @see Sender#offered |
| # |
| proton_caller :available |
| |
| # @!attribute [r] queued |
| # |
| # Returns the number of queued deliveries for a link. |
| # |
| # Links may queue deliveries for a number of reasons. For example, there may |
| # be insufficient credit to send them to the receiver, or they simply may |
| # not have yet had a chance to be written to the wire. |
| # |
| # @return [Fixnum] The number of queued deliveries. |
| # |
| # @see #credit |
| # |
| proton_caller :queued |
| |
| # @!attribute [r] name |
| # |
| # Returns the name of the link. |
| # |
| # @return [String] The name. |
| # |
| proton_caller :name |
| |
| # @!attribute [r] sender? |
| # |
| # Returns if the link is a sender. |
| # |
| # @return [Boolean] True if the link is a sender. |
| # |
| proton_reader :sender, :is_or_get => :is |
| |
| # @!attribute [r] receiver? |
| # |
| # Returns if the link is a receiver. |
| # |
| # @return [Boolean] True if the link is a receiver. |
| # |
| proton_reader :receiver, :is_or_get => :is |
| |
| # @private |
| proton_reader :attachments |
| |
| # Drains excess credit. |
| # |
| # When a link is in drain mode, the sender must use all excess credit |
| # immediately and release any excess credit back to the receiver if there |
| # are no deliveries available to send. |
| # |
| # When invoked on a Sender that is in drain mode, this operation will |
| # release all excess credit back to the receiver and return the number of |
| # credits released back to the sender. If the link is not in drain mode, |
| # this operation is a noop. |
| # |
| # When invoked on a Receiver, this operation will return and reset the |
| # number of credits the sender has released back to it. |
| # |
| # @return [Fixnum] The number of credits drained. |
| # |
| proton_caller :drained |
| |
| # @private |
| include Util::Wrapper |
| |
| # @private |
| def self.wrap(impl) |
| return nil if impl.nil? |
| |
| result = self.fetch_instance(impl, :pn_link_attachments) |
| return result unless result.nil? |
| if Cproton.pn_link_is_sender(impl) |
| return Sender.new(impl) |
| elsif Cproton.pn_link_is_receiver(impl) |
| return Receiver.new(impl) |
| end |
| end |
| |
| # @private |
| def initialize(impl) |
| @impl = impl |
| self.class.store_instance(self, :pn_link_attachments) |
| end |
| |
| # Returns additional error information. |
| # |
| # Whenever a link operation fails (i.e., returns an error code) additional |
| # error details can be obtained from this method. Ther error object that is |
| # returned may also be used to clear the error condition. |
| # |
| # @return [Error] The error. |
| # |
| def error |
| Cproton.pn_link_error(@impl) |
| end |
| |
| # Returns the next link that matches the given state mask. |
| # |
| # @param state_mask [Fixnum] The state mask. |
| # |
| # @return [Sender, Receiver] The next link. |
| # |
| def next(state_mask) |
| return Link.wrap(Cproton.pn_link_next(@impl, state_mask)) |
| end |
| |
| # Returns the locally defined source terminus. |
| # |
| # @return [Terminus] The terminus |
| def source |
| Terminus.new(Cproton.pn_link_source(@impl)) |
| end |
| |
| # Returns the locally defined target terminus. |
| # |
| # @return [Terminus] The terminus. |
| # |
| def target |
| Terminus.new(Cproton.pn_link_target(@impl)) |
| end |
| |
| # Returns a representation of the remotely defined source terminus. |
| # |
| # @return [Terminus] The terminus. |
| # |
| def remote_source |
| Terminus.new(Cproton.pn_link_remote_source(@impl)) |
| end |
| |
| # Returns a representation of the remotely defined target terminus. |
| # |
| # @return [Terminus] The terminus. |
| # |
| def remote_target |
| Terminus.new(Cproton.pn_link_remote_target(@impl)) |
| end |
| |
| # Returns the parent session. |
| # |
| # @return [Session] The session. |
| # |
| def session |
| Session.wrap(Cproton.pn_link_session(@impl)) |
| end |
| |
| # Returns the parent connection. |
| # |
| # @return [Connection] The connection. |
| # |
| def connection |
| self.session.connection |
| end |
| |
| # Returns the parent delivery. |
| # |
| # @return [Delivery] The delivery. |
| # |
| def delivery(tag) |
| Delivery.new(Cproton.pn_delivery(@impl, tag)) |
| end |
| |
| # Returns the current delivery. |
| # |
| # Each link maintains a sequence of deliveries in the order they were |
| # created, along with a reference to the *current* delivery. All send and |
| # receive operations on a link take place on the *current* delivery. If a |
| # link has no current delivery, the current delivery is automatically |
| # pointed to the *next* delivery created on the link. |
| # |
| # Once initialized, the current delivery remains the same until it is |
| # changed by advancing, or until it is settled. |
| # |
| # @see #next |
| # @see Delivery#settle |
| # |
| # @return [Delivery] The current delivery. |
| # |
| def current |
| Delivery.wrap(Cproton.pn_link_current(@impl)) |
| end |
| |
| # Sets the local sender settle mode. |
| # |
| # @param mode [Fixnum] The settle mode. |
| # |
| # @see #SND_UNSETTLED |
| # @see #SND_SETTLED |
| # @see #SND_MIXED |
| # |
| def snd_settle_mode=(mode) |
| Cproton.pn_link_set_snd_settle_mode(@impl, mode) |
| end |
| |
| # Returns the local sender settle mode. |
| # |
| # @return [Fixnum] The local sender settle mode. |
| # |
| # @see #snd_settle_mode |
| # |
| def snd_settle_mode |
| Cproton.pn_link_snd_settle_mode(@impl) |
| end |
| |
| # Sets the local receiver settle mode. |
| # |
| # @param mode [Fixnum] The settle mode. |
| # |
| # @see #RCV_FIRST |
| # @see #RCV_SECOND |
| # |
| def rcv_settle_mode=(mode) |
| Cproton.pn_link_set_rcv_settle_mode(@impl, mode) |
| end |
| |
| # Returns the local receiver settle mode. |
| # |
| # @return [Fixnum] The local receiver settle mode. |
| # |
| def rcv_settle_mode |
| Cproton.pn_link_rcv_settle_mode(@impl) |
| end |
| |
| # @private |
| def _local_condition |
| Cproton.pn_link_condition(@impl) |
| end |
| |
| # @private |
| def _remote_condition |
| Cproton.pn_link_remote_condition(@impl) |
| end |
| |
| def ==(other) |
| other.respond_to?(:impl) && |
| (Cproton.pni_address_of(other.impl) == Cproton.pni_address_of(@impl)) |
| end |
| |
| end |
| |
| end |