All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.flume.channel.ChannelUtils Maven / Gradle / Ivy

There is a newer version: 1.11.0
Show 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.flume.channel;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;

import org.apache.flume.Channel;
import org.apache.flume.ChannelException;
import org.apache.flume.Event;
import org.apache.flume.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 

* A collection of utilities for interacting with {@link Channel} * objects. Use of these utilities prevents error-prone replication * of required transaction usage semantics, and allows for more * concise code. *

*

* However, as a side-effect of its generality, and in particular of * its use of {@link Callable}, any checked exceptions thrown by * user-created transactors will be silently wrapped with {@link * ChannelException} before being propagated. Only direct use of * {@link #transact(Channel,Callable)} suffers from this issue, even * though all other methods are based upon it, because none of the * other methods are capable of producing or allowing checked * exceptions in the first place. *

*/ public class ChannelUtils { private static final Logger logger = LoggerFactory .getLogger(ChannelUtils.class); /** *

* A convenience method for single-event put transactions. *

* @see #transact(Channel,Callable) */ public static void put(final Channel channel, final Event event) throws ChannelException { transact(channel, new Runnable() { @Override public void run() { channel.put(event); } }); } /** *

* A convenience method for multiple-event put transactions. *

* @see #transact(Channel,Callable) */ public static void put(final Channel channel, final Collection events) throws ChannelException { transact(channel, new Runnable() { @Override public void run() { for (Event event : events) { channel.put(event); } } }); } /** *

* A convenience method for single-event take transactions. *

* @return a single event, or null if the channel has none available * @see #transact(Channel,Callable) */ public static Event take(final Channel channel) throws ChannelException { return transact(channel, new Callable() { @Override public Event call() { return channel.take(); } }); } /** *

* A convenience method for multiple-event take transactions. *

* @return a list of at most max events * @see #transact(Channel,Callable) */ public static List take(final Channel channel, final int max) throws ChannelException { return transact(channel, new Callable>() { @Override public List call() { List events = new ArrayList(max); while (events.size() < max) { Event event = channel.take(); if (event == null) { break; } events.add(event); } return events; } }); } /** *

* A convenience method for transactions that don't require a return * value. Simply wraps the transactor using {@link * Executors#callable} and passes that to {@link * #transact(Channel,Callable)}. *

* @see #transact(Channel,Callable) * @see Executors#callable(Runnable) */ public static void transact(Channel channel, Runnable transactor) throws ChannelException { transact(channel, Executors.callable(transactor)); } /** *

* A general optimistic implementation of {@link Transaction} client * semantics. It gets a new transaction object from the * channel, calls begin() on it, and then * invokes the supplied transactor object. If an * exception is thrown, then the transaction is rolled back; * otherwise the transaction is committed and the value returned by * the transactor is returned. In either case, the * transaction is closed before the function exits. All secondary * exceptions (i.e. those thrown by * Transaction.rollback() or * Transaction.close() while recovering from an earlier * exception) are logged, allowing the original exception to be * propagated instead. *

*

* This implementation is optimistic in that it expects transaction * rollback to be infrequent: it will rollback a transaction only * when the supplied transactor throws an exception, * and exceptions are a fairly heavyweight mechanism for handling * frequently-occurring events. *

* @return the value returned by transactor.call() */ public static T transact(Channel channel, Callable transactor) throws ChannelException { Transaction transaction = channel.getTransaction(); boolean committed = false; boolean interrupted = false; try { transaction.begin(); T value = transactor.call(); transaction.commit(); committed = true; return value; } catch (Throwable e) { interrupted = Thread.currentThread().isInterrupted(); try { transaction.rollback(); } catch (Throwable e2) { logger.error("Failed to roll back transaction, exception follows:", e2); } if (e instanceof InterruptedException) { interrupted = true; } else if (e instanceof Error) { throw (Error) e; } else if (e instanceof RuntimeException) { throw (RuntimeException) e; } throw new ChannelException(e); } finally { interrupted = interrupted || Thread.currentThread().isInterrupted(); try { transaction.close(); } catch (Throwable e) { if (committed) { if (e instanceof Error) { throw (Error) e; } else if (e instanceof RuntimeException) { throw (RuntimeException) e; } else { throw new ChannelException(e); } } else { logger.error( "Failed to close transaction after error, exception follows:", e); } } finally { if (interrupted) { Thread.currentThread().interrupt(); } } } } /** Disallows instantiation */ private ChannelUtils() {} }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy