Skip to content

Commit 598efa7

Browse files
Clean up some exception handling code
1 parent e1027c6 commit 598efa7

File tree

2 files changed

+36
-42
lines changed

2 files changed

+36
-42
lines changed

external/flume-sink/src/main/scala/org/apache/spark/streaming/flume/sink/SparkAvroCallbackHandler.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717
package org.apache.spark.streaming.flume.sink
1818

19-
import java.util.concurrent.{ConcurrentLinkedQueue, ConcurrentHashMap, Executors}
19+
import java.util.concurrent.{TimeUnit, ConcurrentLinkedQueue, ConcurrentHashMap, Executors}
2020
import java.util.concurrent.atomic.AtomicLong
2121

2222
import scala.collection.JavaConversions._
@@ -70,7 +70,7 @@ private[flume] class SparkAvroCallbackHandler(val threads: Int, val channel: Cha
7070
*/
7171
override def getEventBatch(n: Int): EventBatch = {
7272
logDebug("Got getEventBatch call from Spark.")
73-
if(stopped) {
73+
if (stopped) {
7474
new EventBatch("Spark sink has been stopped!", "", java.util.Collections.emptyList())
7575
}
7676
val sequenceNumber = seqBase + seqCounter.incrementAndGet()
@@ -141,7 +141,7 @@ private[flume] class SparkAvroCallbackHandler(val threads: Int, val channel: Cha
141141
stopped = true
142142
processorsToShutdown.foreach(_.shutdown())
143143
transactionExecutorOpt.foreach(executor => {
144-
executor.shutdown()
144+
executor.shutdownNow()
145145
})
146146
}
147147
}

external/flume/src/main/scala/org/apache/spark/streaming/flume/FlumePollingInputDStream.scala

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,27 @@ package org.apache.spark.streaming.flume
1818

1919

2020
import java.net.InetSocketAddress
21-
import java.util.concurrent.{LinkedBlockingQueue, TimeUnit, Executors}
21+
import java.util.concurrent.{TimeUnit, LinkedBlockingQueue, Executors}
2222

23-
import org.apache.avro.AvroRemoteException
23+
import com.google.common.base.Throwables
2424

2525
import scala.collection.JavaConversions._
2626
import scala.collection.mutable.ArrayBuffer
2727
import scala.reflect.ClassTag
28+
import scala.util.Try
29+
import scala.util.control.Breaks
2830

2931
import com.google.common.util.concurrent.ThreadFactoryBuilder
3032
import org.apache.avro.ipc.NettyTransceiver
3133
import org.apache.avro.ipc.specific.SpecificRequestor
32-
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory
33-
3434
import org.apache.spark.Logging
3535
import org.apache.spark.storage.StorageLevel
3636
import org.apache.spark.streaming.StreamingContext
3737
import org.apache.spark.streaming.dstream.ReceiverInputDStream
3838
import org.apache.spark.streaming.receiver.Receiver
3939
import org.apache.spark.streaming.flume.sink._
40+
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory
4041

41-
import scala.util.Try
42-
import scala.util.control.Breaks
4342

4443
/**
4544
* A [[ReceiverInputDStream]] that can be used to read data from several Flume agents running
@@ -52,11 +51,11 @@ import scala.util.control.Breaks
5251
* @tparam T Class type of the object of this stream
5352
*/
5453
private[streaming] class FlumePollingInputDStream[T: ClassTag](
55-
@transient _ssc: StreamingContext,
56-
val addresses: Seq[InetSocketAddress],
57-
val maxBatchSize: Int,
58-
val parallelism: Int,
59-
storageLevel: StorageLevel
54+
@transient _ssc: StreamingContext,
55+
val addresses: Seq[InetSocketAddress],
56+
val maxBatchSize: Int,
57+
val parallelism: Int,
58+
storageLevel: StorageLevel
6059
) extends ReceiverInputDStream[SparkFlumeEvent](_ssc) {
6160

6261
override def getReceiver(): Receiver[SparkFlumeEvent] = {
@@ -65,10 +64,10 @@ private[streaming] class FlumePollingInputDStream[T: ClassTag](
6564
}
6665

6766
private[streaming] class FlumePollingReceiver(
68-
addresses: Seq[InetSocketAddress],
69-
maxBatchSize: Int,
70-
parallelism: Int,
71-
storageLevel: StorageLevel
67+
addresses: Seq[InetSocketAddress],
68+
maxBatchSize: Int,
69+
parallelism: Int,
70+
storageLevel: StorageLevel
7271
) extends Receiver[SparkFlumeEvent](storageLevel) with Logging {
7372

7473
lazy val channelFactoryExecutor =
@@ -133,30 +132,27 @@ private[streaming] class FlumePollingReceiver(
133132
}
134133
}.recover {
135134
case e: Exception =>
136-
// Is the exception an interrupted exception? If yes,
137-
// check if the receiver was stopped. If the receiver was stopped,
138-
// simply exit. Else send a Nack and exit.
139-
if (e.isInstanceOf[InterruptedException]) {
140-
if (isStopped()) {
141-
loop.break()
142-
} else {
143-
sendNack(batchReceived, client, seq, e)
144-
}
145-
}
146-
// if there is a cause do the same check as above.
147-
Option(e.getCause) match {
148-
case Some(exception: InterruptedException) =>
135+
Throwables.getRootCause(e) match {
136+
// If the cause was an InterruptedException,
137+
// then check if the receiver is stopped - if yes,
138+
// just break out of the loop. Else send a Nack and
139+
// log a warning.
140+
// In the unlikely case, the cause was not an Exception,
141+
// then just throw it out and exit.
142+
case interrupted: InterruptedException =>
149143
if (isStopped()) {
150144
loop.break()
151145
} else {
152-
sendNack(batchReceived, client, seq, e)
146+
sendNack(batchReceived, client, seq)
147+
logWarning("Interrupted while receiving data from Flume", interrupted)
153148
}
154-
case Some(otherException: Exception) =>
155-
sendNack(batchReceived, client, seq, e)
156-
case Some(majorError: Throwable) =>
157-
throw majorError // kill immediately
158-
case None =>
159-
sendNack(batchReceived, client, seq, e)
149+
case exception: Exception =>
150+
sendNack(batchReceived, client, seq)
151+
logWarning("Error while receiving data from Flume", exception)
152+
case majorError: Throwable =>
153+
// Don't bother with Nack - exit immediately
154+
logError("Major error while receiving data from Flume.", majorError)
155+
throw majorError
160156
}
161157
}
162158
} catch {
@@ -173,7 +169,7 @@ private[streaming] class FlumePollingReceiver(
173169
}
174170

175171
private def sendNack(batchReceived: Boolean, client: SparkFlumeProtocol.Callback,
176-
seq: CharSequence, exception: Exception): Unit = {
172+
seq: CharSequence): Unit = {
177173
Try {
178174
if (batchReceived) {
179175
// Let Flume know that the events need to be pushed back into the channel.
@@ -183,10 +179,8 @@ private[streaming] class FlumePollingReceiver(
183179
}
184180
}.recover({
185181
case e: Exception => logError(
186-
"Sending Nack also failed. A Flume agent is down.")
182+
"Sending Nack also failed. A Flume agent is down.", e)
187183
})
188-
TimeUnit.SECONDS.sleep(2L) // for now just leave this as a fixed 2 seconds.
189-
logWarning("Error while attempting to store events", exception)
190184
}
191185

192186
override def onStop(): Unit = {

0 commit comments

Comments
 (0)