@LifecycleStart public void start() throws IOException { for (final FireDepartment fireDepartment : fireDepartments) { DataSchema schema = fireDepartment.getDataSchema(); final FireChief chief = new FireChief(fireDepartment); List<FireChief> chiefs = this.chiefs.get(schema.getDataSource()); if (chiefs == null) { chiefs = new ArrayList<FireChief>(); this.chiefs.put(schema.getDataSource(), chiefs); } chiefs.add(chief); chief.setName( String.format( "chief-%s[%s]", schema.getDataSource(), fireDepartment.getTuningConfig().getShardSpec().getPartitionNum())); chief.setDaemon(true); chief.start(); } }
public Plumber initPlumber() { synchronized (this) { if (plumber == null) { log.info("Someone get us a plumber!"); plumber = fireDepartment.findPlumber(); log.info("We have our plumber!"); } else { log.warn("Plumber already trained, skipping initPlumber()."); } return plumber; } }
public Firehose initFirehose() { synchronized (this) { if (firehose == null) { try { log.info("Calling the FireDepartment and getting a Firehose."); firehose = fireDepartment.connect(); log.info("Firehose acquired!"); } catch (IOException e) { throw Throwables.propagate(e); } } else { log.warn("Firehose already connected, skipping initFirehose()."); } return firehose; } }
@Override public void run() { plumber = initPlumber(); final Period intermediatePersistPeriod = config.getIntermediatePersistPeriod(); try { plumber.startJob(); // Delay firehose connection to avoid claiming input resources while the plumber is starting // up. firehose = initFirehose(); long nextFlush = new DateTime().plus(intermediatePersistPeriod).getMillis(); while (firehose.hasMore()) { InputRow inputRow = null; try { try { inputRow = firehose.nextRow(); } catch (Exception e) { log.debug(e, "thrown away line due to exception, considering unparseable"); metrics.incrementUnparseable(); continue; } boolean lateEvent = false; boolean indexLimitExceeded = false; try { lateEvent = plumber.add(inputRow) == -1; } catch (IndexSizeExceededException e) { log.info("Index limit exceeded: %s", e.getMessage()); indexLimitExceeded = true; } if (indexLimitExceeded || lateEvent) { metrics.incrementThrownAway(); log.debug("Throwing away event[%s]", inputRow); if (indexLimitExceeded || System.currentTimeMillis() > nextFlush) { plumber.persist(firehose.commit()); nextFlush = new DateTime().plus(intermediatePersistPeriod).getMillis(); } continue; } final Sink sink = plumber.getSink(inputRow.getTimestampFromEpoch()); if ((sink != null && !sink.canAppendRow()) || System.currentTimeMillis() > nextFlush) { plumber.persist(firehose.commit()); nextFlush = new DateTime().plus(intermediatePersistPeriod).getMillis(); } metrics.incrementProcessed(); } catch (ParseException e) { if (inputRow != null) { log.error(e, "unparseable line: %s", inputRow); } metrics.incrementUnparseable(); } } } catch (RuntimeException e) { log.makeAlert( e, "RuntimeException aborted realtime processing[%s]", fireDepartment.getDataSchema().getDataSource()) .emit(); normalExit = false; throw e; } catch (Error e) { log.makeAlert( e, "Exception aborted realtime processing[%s]", fireDepartment.getDataSchema().getDataSource()) .emit(); normalExit = false; throw e; } finally { CloseQuietly.close(firehose); if (normalExit) { plumber.finishJob(); plumber = null; firehose = null; } } }
public FireChief(FireDepartment fireDepartment) { this.fireDepartment = fireDepartment; this.config = fireDepartment.getTuningConfig(); this.metrics = fireDepartment.getMetrics(); }
/** * Tries to extinguish flames in the direction opposite of the next forecast(first) Then goes for * the largest buildings (next) * * @param bribesToUse * @return number of turns used */ public int fireExtinguishAroundHQ(int bribesToUse) { // first get HQ Warehouse ourHQ = player.headquarters; int bribesLeft = Math.min(bribesToUse, player.bribesRemaining); int bribesUsed = 0; if (bribesLeft <= 0) { return 0; } Stack<FireDepartment> fireDepartments = new Stack<>(); for (FireDepartment fdpt : player.fireDepartments) { if (fdpt != null && fdpt.bribed == false && fdpt.health > 0) { fireDepartments.push(fdpt); } } // get the wind direction WeatherStationUtilities.CardinalDirection dir = Enum.valueOf(WeatherStationUtilities.CardinalDirection.class, game.nextForecast.direction); dir = dir.rotate180(); // get the building in the opposite direction Building adjacentUpwindBuilding = ourHQ.getAdjacentBuilding(dir); if (adjacentUpwindBuilding != null && adjacentUpwindBuilding.owner == player) { int numberOfExtinguishes = adjacentUpwindBuilding.fire / 2; int numberOfTurnsToUse = Math.min(bribesLeft, numberOfExtinguishes); numberOfTurnsToUse = Math.min(numberOfTurnsToUse, fireDepartments.size()); for (int bribes = 0; bribes < numberOfTurnsToUse; bribes++) { if (fireDepartments.isEmpty() || bribesLeft <= 0) { return bribesUsed; } FireDepartment dpt = fireDepartments.pop(); dpt.extinguish(adjacentUpwindBuilding); bribesUsed++; bribesLeft--; } } // now evenly use the other 3 buildings List<Building> adjacentUrgentBuildings = new ArrayList<>(); List<Building> closeBuildings = ourHQ.getBuildingsWithinDistance(1); for (Building b : closeBuildings) { if (b != null && b.owner == player && b.fire > 1) { adjacentUrgentBuildings.add(b); } } if (bribesLeft <= 0 || adjacentUrgentBuildings.isEmpty()) { return bribesUsed; } while (bribesLeft >= 0) { // find the highest fire building Building highestFire = adjacentUrgentBuildings.get(0); for (Building b : adjacentUrgentBuildings) { if (b.fire > highestFire.fire) { highestFire = b; } } if (highestFire.fire <= 1 || fireDepartments.empty()) { return bribesUsed; } // put out the highest fire FireDepartment fdpt = fireDepartments.pop(); fdpt.extinguish(highestFire); bribesLeft--; bribesUsed++; } return bribesUsed; }