Package eu.stratosphere.runtime.io.channels

Source Code of eu.stratosphere.runtime.io.channels.OutputChannel

/***********************************************************************************************************************
* Copyright (C) 2010-2014 by the Stratosphere project (http://stratosphere.eu)
*
* Licensed 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 eu.stratosphere.runtime.io.channels;

import eu.stratosphere.nephele.event.task.AbstractEvent;
import eu.stratosphere.nephele.event.task.AbstractTaskEvent;
import eu.stratosphere.nephele.jobgraph.JobID;
import eu.stratosphere.runtime.io.Buffer;
import eu.stratosphere.runtime.io.network.Envelope;
import eu.stratosphere.runtime.io.gates.OutputGate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.util.Arrays;


public class OutputChannel extends Channel {

  private static final Log LOG = LogFactory.getLog(OutputChannel.class);

  private final Object closeLock = new Object();
 
  private final OutputGate outputGate;

  private boolean senderCloseRequested;

  private boolean receiverCloseRequested;

  private int currentSeqNum;

  // -----------------------------------------------------------------------------------------------------------------

  /**
   * Creates a new output channel object.
   *
   * @param outputGate the output gate this channel is connected to
   * @param index the index of the channel in the output gate
   * @param id the ID of the channel
   * @param connectedId the ID of the channel this channel is connected to
   * @param type the type of this channel
   */
  public OutputChannel(OutputGate outputGate, int index, ChannelID id, ChannelID connectedId, ChannelType type) {
    super(index, id, connectedId, type);

    this.outputGate = outputGate;
  }

  // -----------------------------------------------------------------------------------------------------------------
  //                                           Data processing
  // -----------------------------------------------------------------------------------------------------------------

  public void sendBuffer(Buffer buffer) throws IOException, InterruptedException {
    checkStatus();

    // discard empty buffers
    if (buffer.size() == 0) {
      return;
    }

    Envelope envelope = createNextEnvelope();
    envelope.setBuffer(buffer);
    this.envelopeDispatcher.dispatchFromOutputChannel(envelope);
  }

  public void sendEvent(AbstractEvent event) throws IOException, InterruptedException {
    checkStatus();

    Envelope envelope = createNextEnvelope();
    envelope.serializeEventList(Arrays.asList(event));
    this.envelopeDispatcher.dispatchFromOutputChannel(envelope);
  }

  public void sendBufferAndEvent(Buffer buffer, AbstractEvent event) throws IOException, InterruptedException {
    checkStatus();

    Envelope envelope = createNextEnvelope();
    envelope.setBuffer(buffer);
    envelope.serializeEventList(Arrays.asList(event));
    this.envelopeDispatcher.dispatchFromOutputChannel(envelope);
  }

  // -----------------------------------------------------------------------------------------------------------------
  //                                          Event processing
  // -----------------------------------------------------------------------------------------------------------------

  @Override
  public void queueEnvelope(Envelope envelope) {
    if (envelope.hasBuffer()) {
      throw new IllegalStateException("Envelope for OutputChannel has Buffer attached.");
    }

    for (AbstractEvent event : envelope.deserializeEvents()) {
      if (event.getClass() == ChannelCloseEvent.class) {
        synchronized (this.closeLock) {
          this.receiverCloseRequested = true;
          this.closeLock.notifyAll();
        }
      }
      else if (event instanceof AbstractTaskEvent) {
        if (LOG.isDebugEnabled()) {
          LOG.debug("OutputChannel received task event: " + event);
        }
       
        this.outputGate.deliverEvent((AbstractTaskEvent) event);
      }
      else {
        throw new RuntimeException("OutputChannel received an event that is neither close nor task event.");
      }
    }
  }

  // -----------------------------------------------------------------------------------------------------------------
  //                                              Shutdown
  // -----------------------------------------------------------------------------------------------------------------

  public void requestClose() throws IOException, InterruptedException {
    if (this.senderCloseRequested) {
      return;
    }

    this.senderCloseRequested = true;

    Envelope envelope = createNextEnvelope();
    envelope.serializeEventList(Arrays.asList(new ChannelCloseEvent()));
    this.envelopeDispatcher.dispatchFromOutputChannel(envelope);
  }

  @Override
  public boolean isClosed() {
    return this.senderCloseRequested && this.receiverCloseRequested;
  }
 
  public void waitForChannelToBeClosed() throws InterruptedException {
    synchronized (this.closeLock) {
      while (!this.receiverCloseRequested) {
        this.closeLock.wait(1000);
      }
    }
  }

  // -----------------------------------------------------------------------------------------------------------------

  @Override
  public boolean isInputChannel() {
    return false;
  }

  @Override
  public JobID getJobID() {
    return this.outputGate.getJobID();
  }
 
  private void checkStatus() throws IOException {
    if (this.senderCloseRequested) {
      throw new IllegalStateException(String.format("Channel %s already requested to be closed", getID()));
    }
    if (this.receiverCloseRequested) {
      throw new ReceiverAlreadyClosedException();
    }
  }

  private Envelope createNextEnvelope() {
    return new Envelope(this.currentSeqNum++, getJobID(), getID());
  }

  @Override
  public void transferEvent(AbstractEvent event) throws IOException, InterruptedException {
    // TODO remove with pending changes for input side
  }

  @Override
  public void releaseAllResources() {
    // nothing to do for buffer oriented runtime => TODO remove with pending changes for input side
  }

  @Override
  public void destroy() {
    // nothing to do for buffer oriented runtime => TODO remove with pending changes for input side
  }
}
TOP

Related Classes of eu.stratosphere.runtime.io.channels.OutputChannel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.