
org.apache.activemq.apollo.broker.Delivery.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apollo-broker Show documentation
Show all versions of apollo-broker Show documentation
A reliable messaging server.
The newest version!
/**
* 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.
*/
package org.apache.activemq.apollo.broker
import _root_.org.fusesource.hawtdispatch._
import org.fusesource.hawtbuf._
import org.apache.activemq.apollo.filter.Filterable
import org.apache.activemq.apollo.broker.store.StoreUOW
import org.apache.activemq.apollo.util.Log
import java.util.concurrent.atomic.AtomicReference
import org.apache.activemq.apollo.broker.protocol.MessageCodec
object DeliveryProducer extends Log
/**
* A producer which sends Delivery objects to a delivery consumer.
*
* @author Hiram Chirino
*/
trait DeliveryProducer {
import DeliveryProducer._
def dispatch_queue:DispatchQueue
def connection:Option[BrokerConnection] = None
def send_buffer_size = 64*1024
def collocate(value:DispatchQueue):Unit = {
if( value.getTargetQueue ne dispatch_queue.getTargetQueue ) {
debug("co-locating %s with %s", dispatch_queue.getLabel, value.getLabel);
this.dispatch_queue.setTargetQueue(value.getTargetQueue)
}
}
}
/**
* The delivery consumer accepts messages from a delivery producer.
*
* @author Hiram Chirino
*/
trait DeliveryConsumer extends Retained {
def connection:Option[BrokerConnection] = None
def receive_buffer_size = 64*1024
def close_on_drain = browser
def start_from_tail = false
def set_starting_seq(seq:Long) = {}
def user:String = null
def jms_selector:String = null
def browser = false
def exclusive = false
def dispatch_queue:DispatchQueue;
def matches(message:Delivery):Boolean
def connect(producer:DeliveryProducer):DeliverySession
def is_persistent:Boolean
}
abstract class AbstractRetainedDeliveryConsumer extends BaseRetained with DeliveryConsumer
class DeliveryConsumerFilter(val next:DeliveryConsumer) extends DeliveryConsumer {
override def browser: Boolean = next.browser
override def close_on_drain: Boolean = next.close_on_drain
override def connection: Option[BrokerConnection] = next.connection
override def exclusive: Boolean = next.exclusive
override def jms_selector: String = next.jms_selector
override def receive_buffer_size: Int = next.receive_buffer_size
override def set_starting_seq(seq: Long) { next.set_starting_seq(seq) }
override def start_from_tail: Boolean = next.start_from_tail
override def user: String = next.user
def connect(producer: DeliveryProducer): DeliverySession = next.connect(producer)
def dispatch_queue: DispatchQueue = next.dispatch_queue
def is_persistent: Boolean = next.is_persistent
def matches(message: Delivery): Boolean = next.matches(message)
def release() { next.release() }
def retain() { next.retain() }
def retained(): Int = next.retained()
}
/**
* Before a delivery producer can send Delivery objects to a delivery
* consumer, it creates a Delivery session which it uses to send
* the deliveries over.
*
* @author Hiram Chirino
*/
trait DeliverySession extends SessionSink[Delivery] {
def producer:DeliveryProducer
def consumer:DeliveryConsumer
def close:Unit
}
/**
* Abstracts wire protocol message implementations. Each wire protocol
* will provide it's own type of Message.
*
* @author Hiram Chirino
*/
trait Message extends Filterable with Retained {
/**
* The encoder/decoder of the message
*/
def codec:MessageCodec
def headers_as_json = new java.util.HashMap[String, Object]()
def encoded:Buffer = codec.encode(this).buffer
def message_group: String = null
}
/**
*
* A new Delivery object is created every time a message is transfered between a producer and
* it's consumer or consumers. Consumers will retain the object to flow control the producer.
*
*
* Once this object is disposed, the producer is free to send more deliveries to the consumers.
*
*
* @author Hiram Chirino
*/
object Delivery extends Sizer[Delivery] {
def size(value:Delivery):Int = value.size
}
sealed trait DeliveryResult
/**
* message was delivered and processed, does not need redelivery
*/
object Consumed extends DeliveryResult
/**
* The message was delivered but not consumed, it should be redelivered to another consumer ASAP.
* The redelivery counter should increment.
*/
object Delivered extends DeliveryResult
/**
* The message was not delivered so it should be redelivered to another consumer but not effect
* it's redelivery counter.
*/
object Undelivered extends DeliveryResult
/**
* message expired before it could be processed, does not need redelivery
*/
object Expired extends DeliveryResult
/**
* The receiver thinks the message was poison message, it was not successfully
* processed and it should not get redelivered..
*/
object Poisoned extends DeliveryResult
sealed trait RetainAction
object RetainSet extends RetainAction
object RetainRemove extends RetainAction
object RetainIgnore extends RetainAction
class Delivery {
/**
* Where the delivery is originating from.
*/
var sender = List[DestinationAddress]()
/**
* Total size of the delivery. Used for resource allocation tracking
*/
var size:Int = 0
/**
* When the message will expire
*/
var expiration:Long = 0
/**
* Is the delivery persistent?
*/
var persistent:Boolean = false
/**
* the message being delivered
*/
var message: Message = null
/**
* The sequence id the destination assigned the message
*/
var seq:Long = -1
/**
* The id the store assigned the message
*/
var storeKey:Long = -1
/**
* After the store persists the message he may be able to supply us with locator handle
* which will load the message faster than looking it up via the store key.
*/
var storeLocator:AtomicReference[Object] = null
/**
* The transaction the delivery is participating in.
*/
var uow:StoreUOW = null
/**
* The number of redeliveries that this message has seen.
*/
var redeliveries:Short = 0
/**
* Set if the producer requires an ack to be sent back. Consumer
* should execute once the message is processed.
*/
var ack:(DeliveryResult, StoreUOW)=>Unit = null
/**
* Should this message get retained as the last image of a topic?
*/
var retain:RetainAction = RetainIgnore
def copy() = (new Delivery).set(this)
def set(other:Delivery) = {
sender = other.sender
size = other.size
persistent = other.persistent
expiration = other.expiration
size = other.size
seq = other.seq
message = other.message
storeKey = other.storeKey
storeLocator = other.storeLocator
redeliveries = other.redeliveries
retain = other.retain
this
}
def createMessageRecord() = {
val record = message.codec.encode(message)
record.locator = storeLocator
record
}
def redelivered = redeliveries = ((redeliveries+1).min(Short.MaxValue)).toShort
override def toString = {
"Delivery(" +
"sender:"+sender+", "+
"size:"+size+", "+
"message codec:"+message.codec.id+", "+
"expiration:"+expiration+", "+
"persistent:"+persistent+", "+
"redeliveries:"+redeliveries+", "+
"seq:"+seq+", "+
"storeKey:"+storeKey+", "+
"storeLocator:"+storeLocator+", "+
"uow:"+uow+", "+
"ack:"+(ack!=null)+
")"
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy