/*
* Copyright 2014 University of Southern California
*
* 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 edu.usc.pgroup.floe.flake.messaging.sender;
import com.codahale.metrics.MetricRegistry;
import edu.usc.pgroup.floe.flake.FlakeComponent;
import edu.usc.pgroup.floe.thriftgen.TChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zeromq.ZMQ;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author kumbhare
*/
public class SenderFEComponent extends FlakeComponent {
/**
* the global logger instance.
*/
private static final Logger LOGGER =
LoggerFactory.getLogger(SenderFEComponent.class);
/**
* the map of pellet to ports to start the zmq sockets.
* one for each edge in the application graph.
*/
private final Map<String, Integer> pelletPortMap;
/**
* the map of pellet to ports to start the zmq sockets for the dispersion.
*/
private final Map<String, Integer> pelletBackChannelPortMap;
/**
* the map of pellet to list of streams that pellet is subscribed to.
*/
private final Map<String, List<String>> pelletStreamsMap;
/**
* Map of target pellet to channel type (one per edge).
*/
private final Map<String, TChannel> pelletChannelTypeMap;
/**
* Pellet's name to be sent with each message.
*/
private final String myPelletName;
/**
* Application name.
*/
private final String appName;
/**
* constructor.
* @param metricRegistry Metrics registry used to log various metrics.
* @param ctx Shared ZMQ context.
* @param app Application name.
* @param pelletName Pellet's name to be sent with each message.
* @param flakeId flake id to which this sender belongs.
* @param componentName Component name.
* @param portMap the map of ports on which this flake should
* listen on. Note: This is fine here (and not as a
* control signal) because this depends only on
* static application configuration and not on
* @param backChannelPortMap ports for dispersion.
* @param channels Map of target pellet to channel type (one per edge)
* @param streamsMap map from successor pellets to subscribed
* streams.
*/
public SenderFEComponent(final MetricRegistry metricRegistry,
final ZMQ.Context ctx,
final String app,
final String pelletName,
final String flakeId,
final String componentName,
final Map<String, Integer> portMap,
final Map<String, Integer> backChannelPortMap,
final Map<String, TChannel> channels,
final Map<String, List<String>> streamsMap) {
super(metricRegistry, flakeId, componentName, ctx);
this.appName = app;
this.myPelletName = pelletName;
this.pelletPortMap = portMap;
this.pelletBackChannelPortMap = backChannelPortMap;
this.pelletChannelTypeMap = channels;
this.pelletStreamsMap = streamsMap;
}
/**
* Starts all the sub parts of the given component and notifies when
* components starts completely. This will be in a different thread,
* so no need to worry.. block as much as you want.
*
* @param terminateSignalReceiver terminate signal receiver.
*/
@Override
protected final void runComponent(
final ZMQ.Socket terminateSignalReceiver) {
//new SenderMEComponent().start
SenderMEComponent me = new SenderMEComponent(getMetricRegistry(),
getFid(), "ME", getContext());
me.startAndWait();
List<SenderBEComponent> bes = new ArrayList<>();
for (String pellet: pelletPortMap.keySet()) {
int port = pelletPortMap.get(pellet);
int bpPort = pelletBackChannelPortMap.get(pellet);
TChannel channel = pelletChannelTypeMap.get(pellet);
List<String> streams = pelletStreamsMap.get(pellet);
SenderBEComponent be
= new SenderBEComponent(getMetricRegistry(),
getFid(), "BE", getContext(),
port, bpPort, appName, pellet,
channel, streams, myPelletName);
be.startAndWait();
bes.add(be);
}
notifyStarted(true);
terminateSignalReceiver.recv(); //wait for the terminate signal.
me.stopAndWait();
for (SenderBEComponent be: bes) {
be.stopAndWait();
}
notifyStopped(true);
}
}