/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2011, 2015 Oracle and/or its affiliates. All rights reserved.
*
*/
using System;
using System.Collections.Generic;
using System.Text;
using BerkeleyDB.Internal;
namespace BerkeleyDB {
///
/// A class representing a channel in Berkeley DB HA replication manager.
///
public class DbChannel : IDisposable {
private bool isOpen;
private DB_CHANNEL channel;
private uint timeout;
///
/// Close the channel.
///
///
///
/// All channels must be closed before the encompassing environment is
/// closed. Also, all on-going messaging operations on the channel
/// should be allowed to complete before attempting to close the
/// channel.
///
///
/// After close, regardless of its return, the DbChannel may not be
/// accessed again.
///
///
public void Close() {
isOpen = false;
channel.close(0);
}
///
/// Release the resources held by this object, and close the channel if
/// it is still open.
///
public void Dispose() {
if (isOpen)
channel.close(0);
channel.Dispose();
GC.SuppressFinalize(this);
}
///
/// Send a message on the message channel. The message is sent
/// asynchronously. The method does not wait for a response before
/// returning. It usually completes quickly because it only waits for
/// local TCP implementation to accept the bytes into its network data
/// buffer. However, this message could block briefly for longer
/// messages, and/or if the network data buffer is nearly full.
/// It could even block indefinitely if the remote site is slow
/// to read.
///
///
///
/// To block while waiting for a response from a remote site, use
/// instead of this method.
///
///
/// The sent message is received and handled at remote sites using a
/// message dispatch callback, which is configured using
/// . This
/// method may be used within the message dispatch callback on the
/// remote site to send a reply or acknowledgement for messages that it
/// receives and is handling.
///
///
/// This method may be used on channels opened to any destination. See
/// for a list of
/// potential destinations.
///
///
///
/// An array of DatabaseEntry objects. Any flags for the DatabaseEntry
/// objects are ignored.
///
public void SendMessage(DatabaseEntry[] msg) {
int size = msg.Length;
IntPtr[] dbts = new IntPtr[size];
for (int i = 0; i < size; i++)
dbts[i] = DBT.getCPtr(DatabaseEntry.getDBT(msg[i])).Handle;
channel.send_msg(dbts, (uint)size, 0);
}
///
/// Send a message on the message channel. The message is sent
/// synchronously. The method blocks waiting for a response before
/// returning. If a response is not received within the timeout value
/// configured for this request, this method returns with an error
/// condition.
///
///
///
/// To avoid block while waiting for a response from a remote site,
/// use
///
///
/// The message sent by this method is received and handled at remote
/// sites using a message dispatch callback, which is configured using
///
///
///
///
/// DatabaseEntry objects array. Any flags for the DatabaseEntry objects
/// are ignored.
///
///
/// The amount of time that may elapse while this method waits for a
/// response from the remote site. The timeout value must be specified
/// as an unsigned 32-bit number of microseconds, limiting the maximum
/// timeout to roughly 71 minutes. A timeout value of 0 indicates that
/// the channel's default timeout value should be used. This default is
/// configured using .
///
/// The response from remote site
public DatabaseEntry SendRequest(
DatabaseEntry[] request, uint timeout) {
int size = request.Length;
IntPtr[] dbts = new IntPtr[size];
for (int i = 0; i < size; i++)
dbts[i] = DBT.getCPtr(DatabaseEntry.getDBT(request[i])).Handle;
DatabaseEntry response = new DatabaseEntry();
channel.send_request(dbts, (uint)size, response, timeout, 0);
return response;
}
///
/// Send a message on the message channel. The message is sent
/// synchronously. The method blocks waiting for a response before
/// returning. If a response is not received within the timeout value
/// configured for this request, this method returns with an error
/// condition.
///
///
///
/// To avoid block while waiting for a response from a remote site,
/// use
///
///
/// The message sent by this method is received and handled at remote
/// sites using a message dispatch callback, which is configured using
///
///
///
///
/// DatabaseEntry objects array. Any flags for the DatabaseEntry objects
/// are ignored.
///
/// Size of bulk buffer
///
/// The amount of time that may elapse while this method waits for a
/// response from the remote site. The timeout value must be specified
/// as an unsigned 32-bit number of microseconds, limiting the maximum
/// timeout to roughly 71 minutes. A timeout value of 0 indicates that
/// the channel's default timeout value should be used. This default is
/// configured using .
///
/// Multiple responses from the remote site.
public MultipleDatabaseEntry SendRequest(
DatabaseEntry[] request, int bufferSize, uint timeout) {
int size = request.Length;
IntPtr[] dbts = new IntPtr[size];
for (int i = 0; i < size; i++)
dbts[i] = DBT.getCPtr(DatabaseEntry.getDBT(request[i])).Handle;
DatabaseEntry data = new DatabaseEntry();
data.UserData = new byte[bufferSize];
channel.send_request(dbts, (uint)size, data, timeout,
DbConstants.DB_MULTIPLE);
MultipleDatabaseEntry response = new MultipleDatabaseEntry(data);
return response;
}
///
/// Set the default timeout value. It is used by
/// .
///
///
///
/// The timeout is the amount of time that may elapse while
/// waits for a message response. It must be
/// specified as an unsigned 32-bit number of microseconds, limiting the
/// maximum timeout to roughly 71 minutes.
///
///
public uint Timeout {
get {
return timeout;
}
set {
channel.set_timeout(timeout);
}
}
internal DbChannel(DB_CHANNEL channel) {
this.channel = channel;
isOpen = true;
timeout = 0;
}
}
}