text:
package alluxio.master.block;

import alluxio.Configuration;
import alluxio.Constants;
import alluxio.MasterStorageTierAssoc;
import alluxio.PropertyKey;
import alluxio.Server;
import alluxio.StorageTierAssoc;
import alluxio.client.block.options.GetWorkerReportOptions;
import alluxio.client.block.options.GetWorkerReportOptions.WorkerRange;
import alluxio.clock.SystemClock;
import alluxio.collections.ConcurrentHashSet;
import alluxio.collections.IndexDefinition;
import alluxio.collections.IndexedSet;
import alluxio.exception.BlockInfoException;
import alluxio.exception.ExceptionMessage;
import alluxio.exception.status.InvalidArgumentException;
import alluxio.exception.status.NotFoundException;
import alluxio.exception.status.UnavailableException;
import alluxio.heartbeat.HeartbeatContext;
import alluxio.heartbeat.HeartbeatExecutor;
import alluxio.heartbeat.HeartbeatThread;
import alluxio.master.CoreMaster;
import alluxio.master.CoreMasterContext;
import alluxio.master.block.meta.MasterBlockInfo;
import alluxio.master.block.meta.MasterBlockLocation;
import alluxio.master.block.meta.MasterWorkerInfo;
import alluxio.master.journal.JournalContext;
import alluxio.master.metrics.MetricsMaster;
import alluxio.metrics.Metric;
import alluxio.metrics.MetricsSystem;
import alluxio.proto.journal.Block.BlockContainerIdGeneratorEntry;
import alluxio.proto.journal.Block.BlockInfoEntry;
import alluxio.proto.journal.Block.DeleteBlockEntry;
import alluxio.proto.journal.Journal.JournalEntry;
import alluxio.thrift.BlockMasterClientService;
import alluxio.thrift.BlockMasterWorkerService;
import alluxio.thrift.Command;
import alluxio.thrift.CommandType;
import alluxio.thrift.RegisterWorkerTOptions;
import alluxio.util.CommonUtils;
import alluxio.util.IdUtils;
import alluxio.util.executor.ExecutorServiceFactories;
import alluxio.util.executor.ExecutorServiceFactory;
import alluxio.util.network.NetworkAddressUtils;
import alluxio.wire.Address;
import alluxio.wire.BlockInfo;
import alluxio.wire.BlockLocation;
import alluxio.wire.ConfigProperty;
import alluxio.wire.WorkerInfo;
import alluxio.wire.WorkerNetAddress;

import com.codahale.metrics.Gauge;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jersey.repackaged.com.google.common.base.Preconditions;
import org.apache.thrift.TProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.UnknownHostException;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.NotThreadSafe;

/**
 * This block master manages the metadata for all the blocks and block workers in Alluxio.
 */
@NotThreadSafe // TODO(jiri): make thread-safe (c.f. ALLUXIO-1664)
public final class DefaultBlockMaster extends CoreMaster implements BlockMaster {
  private static final Logger LOG = LoggerFactory.getLogger(DefaultBlockMaster.class);
  private static final Set<Class<? extends Server>> DEPS =
      ImmutableSet.<Class<? extends Server>>of(MetricsMaster.class);

  /**
   * The number of container ids to 'reserve' before having to journal container id state. This
   * allows the master to return container ids within the reservation, without having to write to
   * the journal.
   */
  private static final long CONTAINER_ID_RESERVATION_SIZE = 1000;

  // Worker metadata management.
  private static final IndexDefinition<MasterWorkerInfo, Long> ID_INDEX =
      new IndexDefinition<MasterWorkerInfo, Long>(true) {
        @Override
        public Long getFieldValue(MasterWorkerInfo o) {
          return o.getId();
        }
      };

  private static final IndexDefinition<MasterWorkerInfo, WorkerNetAddress> ADDRESS_INDEX =
      new IndexDefinition<MasterWorkerInfo, WorkerNetAddress>(true) {
        @Override
        public WorkerNetAddress getFieldValue(MasterWorkerInfo o) {
          return o.getWorkerAddress();
        }
      };

  /**
   * Concurrency and locking in the BlockMaster
   *
   * The block master uses concurrent data structures to allow non-conflicting concurrent access.
   * This means each piece of metadata should be locked individually. There are two types of
   * metadata in the {@link DefaultBlockMaster}; {@link MasterBlockInfo} and
   * {@link MasterWorkerInfo}.
   * Individual objects must be locked before modifying the object, or reading a modifiable field
   * of an object. This will protect the internal integrity of the metadata object.
   *
   * Lock ordering must be preserved in order to prevent deadlock. If both a worker and block
   * metadata must be locked at the same time, the worker metadata ({@link MasterWorkerInfo})
   * must be locked before the block metadata ({@link MasterBlockInfo}).
   *
   * It should not be the case that multiple worker metadata must be locked at the same time, or
   * multiple block metadata must be locked at the same time. Operations involving different
   * workers or different blocks should be able to be performed independently.
   */

  // Block metadata management.
  /** Blocks on all workers, including active and lost blocks. This state must be journaled. */
  private final ConcurrentHashMap<Long, MasterBlockInfo> mBlocks =
      new ConcurrentHashMap<>(8192, 0.90f, 64);
  /** Keeps track of blocks which are no longer in Alluxio storage. */
  private final ConcurrentHashSet<Long> mLostBlocks = new ConcurrentHashSet<>(64, 0.90f, 64);

  /** This state must be journaled. */
  @GuardedBy("itself")
  private final BlockContainerIdGenerator mBlockContainerIdGenerator =
      new BlockContainerIdGenerator();

  /**
   * Mapping between all possible storage level aliases and their ordinal position. This mapping
   * forms a total ordering on all storage level aliases in the system, and must be consistent
   * across masters.
   */
  private final StorageTierAssoc mGlobalStorageTierAssoc;

  /** Keeps track of workers which are in communication with the master. */
  private final IndexedSet<MasterWorkerInfo> mWorkers =
      new IndexedSet<>(ID_INDEX, ADDRESS_INDEX);
  /** Keeps track of workers which are no longer in communication with the master. */
  private final IndexedSet<MasterWorkerInfo> mLostWorkers =
      new IndexedSet<>(ID_INDEX, ADDRESS_INDEX);
  /** Worker is not visualable until registration completes. */
  private final IndexedSet<MasterWorkerInfo> mTempWorkers =
      new IndexedSet<>(ID_INDEX, ADDRESS_INDEX);

  /** Listeners to call when lost workers are found. */
  private final List<Consumer<Address>> mLostWorkerFoundListeners
      = new ArrayList<>();

  /** Listeners to call when workers are lost. */
  private final List<Consumer<Address>> mWorkerLostListeners = new ArrayList<>();

  /** Listeners to call when a new worker registers. */
  private final List<BiConsumer<Address, List<ConfigProperty>>> mWorkerRegisteredListeners
      = new ArrayList<>();

  /** Handle to the metrics master. */
  private final MetricsMaster mMetricsMaster;

  /**
   * The service that detects lost worker nodes, and tries to restart the failed workers.
   * We store it here so that it can be accessed from tests.
   */
  @SuppressFBWarnings("URF_UNREAD_FIELD")
  private Future<?> mLostWorkerDetectionService;

  /** The value of the 'next container id' last journaled. */
  @GuardedBy("mBlockContainerIdGenerator")
  private long mJournaledNextContainerId = 0;

  /**
   * Creates a new instance of {@link DefaultBlockMaster}.
   *
   * @param metricsMaster the metrics master
   * @param masterContext the context for Alluxio master
   */
  DefaultBlockMaster(MetricsMaster metricsMaster, CoreMasterContext masterContext) {
    this(metricsMaster, masterContext, new SystemClock(),
        ExecutorServiceFactories.cachedThreadPool(Constants.BLOCK_MASTER_NAME));
  }

  /**
   * Creates a new instance of {@link DefaultBlockMaster}.
   *
   * @param metricsMaster the metrics master
   * @param masterContext the context for Alluxio master
   * @param clock the clock to use for determining the time
   * @param executorServiceFactory a factory for creating the executor service to use for running
   *        maintenance threads
   */
  DefaultBlockMaster(MetricsMaster metricsMaster, CoreMasterContext masterContext, Clock clock,
      ExecutorServiceFactory executorServiceFactory) {
    super(masterContext, clock, executorServiceFactory);
    Preconditions.checkNotNull(metricsMaster, "metricsMaster");
    mGlobalStorageTierAssoc = new MasterStorageTierAssoc();
    mMetricsMaster = metricsMaster;
    Metrics.registerGauges(this);
  }

  @Override
  public Map<String, TProcessor> getServices() {
    Map<String, TProcessor> services = new HashMap<>();
    services.put(Constants.BLOCK_MASTER_CLIENT_SERVICE_NAME,
        new BlockMasterClientService.Processor<>(new BlockMasterClientServiceHandler(this)));
    services.put(Constants.BLOCK_MASTER_WORKER_SERVICE_NAME,
        new BlockMasterWorkerService.Processor<>(new BlockMasterWorkerServiceHandler(this)));
    return services;
  }

  @Override
  public String getName() {
    return Constants.BLOCK_MASTER_NAME;
  }

  @Override
  public void processJournalEntry(JournalEntry entry) throws IOException {
    // TODO(gene): A better way to process entries besides a huge switch?
    if (entry.hasBlockContainerIdGenerator()) {
      mJournaledNextContainerId = (entry.getBlockContainerIdGenerator()).getNextContainerId();
      mBlockContainerIdGenerator.setNextContainerId((mJournaledNextContainerId));
    } else if (entry.hasDeleteBlock()) {
      mBlocks.remove(entry.getDeleteBlock().getBlockId());
    } else if (entry.hasBlockInfo()) {
      BlockInfoEntry blockInfoEntry = entry.getBlockInfo();
      if (mBlocks.containsKey(blockInfoEntry.getBlockId())) {
        // Update the existing block info.
        MasterBlockInfo blockInfo = mBlocks.get(blockInfoEntry.getBlockId());
        blockInfo.updateLength(blockInfoEntry.getLength());
      } else {
        mBlocks.put(blockInfoEntry.getBlockId(), new MasterBlockInfo(blockInfoEntry.getBlockId(),
            blockInfoEntry.getLength()));
      }
    } else {
      throw new IOException(ExceptionMessage.UNEXPECTED_JOURNAL_ENTRY.getMessage(entry));
    }
  }

  @Override
  public void resetState() {
    mBlocks.clear();
    mJournaledNextContainerId = 0;
    mBlockContainerIdGenerator.setNextContainerId(0);
  }

  @Override
  public Iterator<JournalEntry> getJournalEntryIterator() {
    final Iterator<MasterBlockInfo> it = mBlocks.values().iterator();
    Iterator<JournalEntry> blockIterator = new Iterator<JournalEntry>() {
      @Override
      public boolean hasNext() {
        return it.hasNext();
      }

      @Override
      public JournalEntry next() {
        if (!hasNext()) {
          throw new NoSuchElementException();
        }
        MasterBlockInfo info = it.next();
        BlockInfoEntry blockInfoEntry =
            BlockInfoEntry.newBuilder().setBlockId(info.getBlockId())
                .setLength(info.getLength()).build();
        return JournalEntry.newBuilder().setBlockInfo(blockInfoEntry).build();
      }

      @Override
      public void remove() {
        throw new UnsupportedOperationException("BlockMaster#Iterator#remove is not supported.");
      }
    };

    return Iterators
        .concat(CommonUtils.singleElementIterator(getContainerIdJournalEntry()), blockIterator);
  }

  @Override
  public void start(Boolean isLeader) throws IOException {
    super.start(isLeader);
    if (isLeader) {
      mLostWorkerDetectionService = getExecutorService().submit(new HeartbeatThread(
          HeartbeatContext.MASTER_LOST_WORKER_DETECTION, new LostWorkerDetectionHeartbeatExecutor(),
          (int) Configuration.getMs(PropertyKey.MASTER_WORKER_HEARTBEAT_INTERVAL)));
    }
  }

  @Override
  public int getWorkerCount() {
    return mWorkers.size();
  }

  @Override
  public int getLostWorkerCount() {
    return mLostWorkers.size();
  }

  @Override
  public long getCapacityBytes() {
    long ret = 0;
    for (MasterWorkerInfo worker : mWorkers) {
      synchronized (worker) {
        ret += worker.getCapacityBytes();
      }
    }
    return ret;
  }

  @Override
  public StorageTierAssoc getGlobalStorageTierAssoc() {
    return mGlobalStorageTierAssoc;
  }

  @Override
  public long getUsedBytes() {
    long ret = 0;
    for (MasterWorkerInfo worker : mWorkers) {
      synchronized (worker) {
        ret += worker.getUsedBytes();
      }
    }
    return ret;
  }

  @Override
  public List<WorkerInfo> getWorkerInfoList() throws UnavailableException {
    if (mSafeModeManager.isInSafeMode()) {
      throw new UnavailableException(ExceptionMessage.MASTER_IN_SAFEMODE.getMessage());
    }
    List<WorkerInfo> workerInfoList = new ArrayList<>(mWorkers.size());
    for (MasterWorkerInfo worker : mWorkers) {
      synchronized (worker) {
        workerInfoList.add(worker.generateWorkerInfo(null, true));
      }
    }
    return workerInfoList;
  }

  @Override
  public List<WorkerInfo> getLostWorkersInfoList() throws UnavailableException {
    if (mSafeModeManager.isInSafeMode()) {
      throw new UnavailableException(ExceptionMessage.MASTER_IN_SAFEMODE.getMessage());
    }
    List<WorkerInfo> workerInfoList = new ArrayList<>(mLostWorkers.size());
    for (MasterWorkerInfo worker : mLostWorkers) {
      synchronized (worker) {
        workerInfoList.add(worker.generateWorkerInfo(null, false));
      }
    }
    Collections.sort(workerInfoList, new WorkerInfo.LastContactSecComparator());
    return workerInfoList;
  }

  @Override
  public List<WorkerInfo> getWorkerReport(GetWorkerReportOptions options)
      throws UnavailableException, InvalidArgumentException {
    if (mSafeModeManager.isInSafeMode()) {
      throw new UnavailableException(ExceptionMessage.MASTER_IN_SAFEMODE.getMessage());
    }

    Set<MasterWorkerInfo> selectedLiveWorkers = new HashSet<>();
    Set<MasterWorkerInfo> selectedLostWorkers = new HashSet<>();
    WorkerRange workerRange = options.getWorkerRange();
    switch (workerRange) {
      case ALL:
        selectedLiveWorkers.addAll(mWorkers);
        selectedLostWorkers.addAll(mLostWorkers);
        break;
      case LIVE:
        selectedLiveWorkers.addAll(mWorkers);
        break;
      case LOST:
        selectedLostWorkers.addAll(mLostWorkers);
        break;
      case SPECIFIED:
        Set<String> addresses = options.getAddresses();
        Set<String> workerNames = new HashSet<>();

        selectedLiveWorkers = selectInfoByAddress(addresses, mWorkers, workerNames);
        selectedLostWorkers = selectInfoByAddress(addresses, mLostWorkers, workerNames);

        if (!addresses.isEmpty()) {
          String info = String.format("Unrecognized worker names: %s%n"
                  + "Supported worker names: %s%n",
              addresses.toString(), workerNames.toString());
          throw new InvalidArgumentException(info);
        }
        break;
      default:
        throw new InvalidArgumentException("Unrecognized worker range: " + workerRange);
    }

    List<WorkerInfo> workerInfoList = new ArrayList<>();
    for (MasterWorkerInfo worker : selectedLiveWorkers) {
      synchronized (worker) {
        workerInfoList.add(worker.generateWorkerInfo(options.getFieldRange(), true));
      }
    }
    for (MasterWorkerInfo worker : selectedLostWorkers) {
      synchronized (worker) {
        workerInfoList.add(worker.generateWorkerInfo(options.getFieldRange(), false));
      }
    }
    return workerInfoList;
  }

  @Override
  public void removeBlocks(List<Long> blockIds, boolean delete) throws UnavailableException {
    try (JournalContext journalContext = createJournalContext()) {
      for (long blockId : blockIds) {
        MasterBlockInfo block = mBlocks.get(blockId);
        if (block == null) {
          continue;
        }
        HashSet<Long> workerIds = new HashSet<>();

        synchronized (block) {
          // Technically, 'block' should be confirmed to still be in the data structure. A
          // concurrent removeBlock call can remove it. However, we are intentionally ignoring this
          // race, since deleting the same block again is a noop.
          workerIds.addAll(block.getWorkers());
          // Two cases here:
          // 1) For delete: delete the block metadata.
          // 2) For free: keep the block metadata. mLostBlocks will be changed in
          // processWorkerRemovedBlocks
          if (delete) {
            // Make sure blockId is removed from mLostBlocks when the block metadata is deleted.
            // Otherwise blockId in mLostBlock can be dangling index if the metadata is gone.
            mLostBlocks.remove(blockId);
            if (mBlocks.remove(blockId) != null) {
              JournalEntry entry = JournalEntry.newBuilder()
                  .setDeleteBlock(DeleteBlockEntry.newBuilder().setBlockId(blockId)).build();
              journalContext.append(entry);
            }
          }
        }

        // Outside of locking the block. This does not have to be synchronized with the block
        // metadata, since it is essentially an asynchronous signal to the worker to remove the
        // block.
        for (long workerId : workerIds) {
          MasterWorkerInfo worker = mWorkers.getFirstByField(ID_INDEX, workerId);
          if (worker != null) {
            synchronized (worker) {
              worker.updateToRemovedBlock(true, blockId);
            }
          }
        }
      }
    }
  }

  @Override
  public void validateBlocks(Function<Long, Boolean> validator, boolean repair)
      throws UnavailableException {
    List<Long> invalidBlocks =
        mBlocks.keySet().stream().filter((blockId) -> !validator.apply(blockId))
            .collect(Collectors.toList());
    if (!invalidBlocks.isEmpty()) {
      long limit = 100;
      List<Long> loggedBlocks = invalidBlocks.stream().limit(limit).collect(Collectors.toList());
      LOG.warn("Found {} orphan blocks without corresponding file metadata.", invalidBlocks.size());
      if (invalidBlocks.size() > limit) {
        LOG.warn("The first {} orphan blocks include {}.", limit, loggedBlocks);
      } else {
        LOG.warn("The orphan blocks include {}.", loggedBlocks);
      }
      if (repair) {
        LOG.warn("Deleting {} orphan blocks.", invalidBlocks.size());
        removeBlocks(invalidBlocks, true);
      } else {
        LOG.warn("Restart Alluxio master with {}=true to delete the blocks and repair the system.",
            PropertyKey.Name.MASTER_STARTUP_BLOCK_INTEGRITY_CHECK_ENABLED);
      }
    }
  }

  /**
   * @return a new block container id
   */
  @Override
  public long getNewContainerId() throws UnavailableException {
    synchronized (mBlockContainerIdGenerator) {
      long containerId = mBlockContainerIdGenerator.getNewContainerId();
      if (containerId < mJournaledNextContainerId) {
        // This container id is within the reserved container ids, so it is safe to return the id
        // without having to write anything to the journal.
        return containerId;
      }
      // This container id is not safe with respect to the last journaled container id.
      // Therefore, journal the new state of the container id. This implies that when a master
      // crashes, the container ids within the reservation which have not been used yet will
      // never be used. This is a tradeoff between fully utilizing the container id space, vs.
      // improving master scalability.
      // TODO(gpang): investigate if dynamic reservation sizes could be effective

      // Set the next id to journal with a reservation of container ids, to avoid having to write
      // to the journal for ids within the reservation.
      mJournaledNextContainerId = containerId + CONTAINER_ID_RESERVATION_SIZE;
      try (JournalContext journalContext = createJournalContext()) {
        // This must be flushed while holding the lock on mBlockContainerIdGenerator, in order to
        // prevent subsequent calls to return ids that have not been journaled and flushed.
        journalContext.append(getContainerIdJournalEntry());
      }
      return containerId;
    }
  }

  /**
   * @return a {@link JournalEntry} representing the state of the container id generator
   */
  private JournalEntry getContainerIdJournalEntry() {
    BlockContainerIdGeneratorEntry blockContainerIdGenerator =
        BlockContainerIdGeneratorEntry.newBuilder().setNextContainerId(mJournaledNextContainerId)
            .build();
    return JournalEntry.newBuilder().setBlockContainerIdGenerator(blockContainerIdGenerator)
        .build();
  }

  // TODO(binfan): check the logic is correct or not when commitBlock is a retry
  @Override
  public void commitBlock(long workerId, long usedBytesOnTier, String tierAlias, long blockId,
      long length) throws NotFoundException, UnavailableException {
    LOG.debug("Commit block from workerId: {}, usedBytesOnTier: {}, blockId: {}, length: {}",
        workerId, usedBytesOnTier, blockId, length);

    MasterWorkerInfo worker = mWorkers.getFirstByField(ID_INDEX, workerId);
    // TODO(peis): Check lost workers as well.
    if (worker == null) {
      throw new NotFoundException(ExceptionMessage.NO_WORKER_FOUND.getMessage(workerId));
    }

    // Lock the worker metadata first.
    try (JournalContext journalContext = createJournalContext()) {
      synchronized (worker) {
        // Loop until block metadata is successfully locked.
        while (true) {
          boolean newBlock = false;
          MasterBlockInfo block = mBlocks.get(blockId);
          if (block == null) {
            // The block metadata doesn't exist yet.
            block = new MasterBlockInfo(blockId, length);
            newBlock = true;
          }

          // Lock the block metadata.
          synchronized (block) {
            boolean writeJournal = false;
            if (newBlock) {
              if (mBlocks.putIfAbsent(blockId, block) != null) {
                // Another thread already inserted the metadata for this block, so start loop over.
                continue;
              }
              // Successfully added the new block metadata. Append a journal entry for the new
              // metadata.
              writeJournal = true;
            } else if (block.getLength() != length && block.getLength() == Constants.UNKNOWN_SIZE) {
              // The block size was previously unknown. Update the block size with the committed
              // size, and append a journal entry.
              block.updateLength(length);
              writeJournal = true;
            }
            if (writeJournal) {
              BlockInfoEntry blockInfo =
                  BlockInfoEntry.newBuilder().setBlockId(blockId).setLength(length).build();
              journalContext.append(JournalEntry.newBuilder().setBlockInfo(blockInfo).build());
            }
            // At this point, both the worker and the block metadata are locked.

            // Update the block metadata with the new worker location.
            block.addWorker(workerId, tierAlias);
            // This worker has this block, so it is no longer lost.
            mLostBlocks.remove(blockId);

            // Update the worker information for this new block.
            // TODO(binfan): when retry commitBlock on master is expected, make sure metrics are not
            // double counted.
            worker.addBlock(blockId);
            worker.updateUsedBytes(tierAlias, usedBytesOnTier);
            worker.updateLastUpdatedTimeMs();
          }
          break;
        }
      }
    }
  }

  @Override
  public void commitBlockInUFS(long blockId, long length) throws UnavailableException {
    LOG.debug("Commit block in ufs. blockId: {}, length: {}", blockId, length);
    if (mBlocks.get(blockId) != null) {
      // Block metadata already exists, so do not need to create a new one.
      return;
    }

    // The block has not been committed previously, so add the metadata to commit the block.
    MasterBlockInfo block = new MasterBlockInfo(blockId, length);
    try (JournalContext journalContext = createJournalContext()) {
      synchronized (block) {
        if (mBlocks.putIfAbsent(blockId, block) == null) {
          // Successfully added the new block metadata. Append a journal entry for the new metadata.
          BlockInfoEntry blockInfo =
              BlockInfoEntry.newBuilder().setBlockId(blockId).setLength(length).build();
          journalContext.append(JournalEntry.newBuilder().setBlockInfo(blockInfo).build());
        }
      }
    }
  }

  @Override
  public BlockInfo getBlockInfo(long blockId) throws BlockInfoException, UnavailableException {
    MasterBlockInfo block = mBlocks.get(blockId);
    if (block == null) {
      throw new BlockInfoException(ExceptionMessage.BLOCK_META_NOT_FOUND, blockId);
    }
    synchronized (block) {
      return generateBlockInfo(block);
    }
  }

  @Override
  public List<BlockInfo> getBlockInfoList(List<Long> blockIds) throws UnavailableException {
    List<BlockInfo> ret = new ArrayList<>(blockIds.size());
    for (long blockId : blockIds) {
      MasterBlockInfo block = mBlocks.get(blockId);
      if (block == null) {
        continue;
      }
      synchronized (block) {
        ret.add(generateBlockInfo(block));
      }
    }
    return ret;
  }

  @Override
  public Map<String, Long> getTotalBytesOnTiers() {
    Map<String, Long> ret = new HashMap<>();
    for (MasterWorkerInfo worker : mWorkers) {
      synchronized (worker) {
        for (Map.Entry<String, Long> entry : worker.getTotalBytesOnTiers().entrySet()) {
          Long total = ret.get(entry.getKey());
          ret.put(entry.getKey(), (total == null ? 0L : total) + entry.getValue());
        }
      }
    }
    return ret;
  }

  @Override
  public Map<String, Long> getUsedBytesOnTiers() {
    Map<String, Long> ret = new HashMap<>();
    for (MasterWorkerInfo worker : mWorkers) {
      synchronized (worker) {
        for (Map.Entry<String, Long> entry : worker.getUsedBytesOnTiers().entrySet()) {
          Long used = ret.get(entry.getKey());
          ret.put(entry.getKey(), (used == null ? 0L : used) + entry.getValue());
        }
      }
    }
    return ret;
  }

  /**
   * Find a worker which is considered lost or just gets its id.
   * @param workerNetAddress the address used to find a worker
   * @return a {@link MasterWorkerInfo} which is presented in master but not registered,
   *         or null if not worker is found.
   */
  @Nullable
  private MasterWorkerInfo findUnregisteredWorker(WorkerNetAddress workerNetAddress) {
    for (IndexedSet<MasterWorkerInfo> workers: Arrays.asList(mTempWorkers, mLostWorkers)) {
      MasterWorkerInfo worker = workers.getFirstByField(ADDRESS_INDEX, workerNetAddress);
      if (worker != null) {
        return worker;
      }
    }
    return null;
  }

  /**
   * Find a worker which is considered lost or just gets its id.
   * @param workerId the id used to find a worker
   * @return a {@link MasterWorkerInfo} which is presented in master but not registered,
   *         or null if not worker is found.
   */
  @Nullable
  private MasterWorkerInfo findUnregisteredWorker(long workerId) {
    for (IndexedSet<MasterWorkerInfo> workers: Arrays.asList(mTempWorkers, mLostWorkers)) {
      MasterWorkerInfo worker = workers.getFirstByField(ID_INDEX, workerId);
      if (worker != null) {
        return worker;
      }
    }
    return null;
  }

  /**
   * Re-register a lost worker or complete registration after getting a worker id.
   *
   * @param workerId the worker id to register
   */
  @Nullable
  private MasterWorkerInfo registerWorkerInternal(long workerId) {
    for (IndexedSet<MasterWorkerInfo> workers: Arrays.asList(mTempWorkers, mLostWorkers)) {
      MasterWorkerInfo worker = workers.getFirstByField(ID_INDEX, workerId);
      if (worker == null) {
        continue;
      }

      synchronized (worker) {
        worker.updateLastUpdatedTimeMs();
        mWorkers.add(worker);
        workers.remove(worker);
        if (workers == mLostWorkers) {
          for (Consumer<Address> function : mLostWorkerFoundListeners) {
            function.accept(new Address(worker.getWorkerAddress().getHost(),
                  worker.getWorkerAddress().getRpcPort()));
          }
          LOG.warn("A lost worker {} has requested its old id {}.",
              worker.getWorkerAddress(), worker.getId());
        }
      }

      return worker;
    }
    return null;
  }

  @Override
  public long getWorkerId(WorkerNetAddress workerNetAddress) {
    // TODO(gpang): Clone WorkerNetAddress in case thrift re-uses the object. Does thrift re-use it?
    MasterWorkerInfo existingWorker = mWorkers.getFirstByField(ADDRESS_INDEX, workerNetAddress);
    if (existingWorker != null) {
      // This worker address is already mapped to a worker id.
      long oldWorkerId = existingWorker.getId();
      LOG.warn("The worker {} already exists as id {}.", workerNetAddress, oldWorkerId);
      return oldWorkerId;
    }

    existingWorker = findUnregisteredWorker(workerNetAddress);
    if (existingWorker != null) {
      return existingWorker.getId();
    }

    // Generate a new worker id.
    long workerId = IdUtils.getRandomNonNegativeLong();
    while (!mTempWorkers.add(new MasterWorkerInfo(workerId, workerNetAddress))) {
      workerId = IdUtils.getRandomNonNegativeLong();
    }

    LOG.info("getWorkerId(): WorkerNetAddress: {} id: {}", workerNetAddress, workerId);
    return workerId;
  }

  @Override
  public void workerRegister(long workerId, List<String> storageTiers,
      Map<String, Long> totalBytesOnTiers, Map<String, Long> usedBytesOnTiers,
      Map<String, List<Long>> currentBlocksOnTiers,
      RegisterWorkerTOptions options) throws NotFoundException {

    MasterWorkerInfo worker = mWorkers.getFirstByField(ID_INDEX, workerId);

    if (worker == null) {
      worker = findUnregisteredWorker(workerId);
    }

    if (worker == null) {
      throw new NotFoundException(ExceptionMessage.NO_WORKER_FOUND.getMessage(workerId));
    }

    // Gather all blocks on this worker.
    HashSet<Long> blocks = new HashSet<>();
    for (List<Long> blockIds : currentBlocksOnTiers.values()) {
      blocks.addAll(blockIds);
    }

    synchronized (worker) {
      worker.updateLastUpdatedTimeMs();
      // Detect any lost blocks on this worker.
      Set<Long> removedBlocks = worker.register(mGlobalStorageTierAssoc, storageTiers,
          totalBytesOnTiers, usedBytesOnTiers, blocks);
      processWorkerRemovedBlocks(worker, removedBlocks);
      processWorkerAddedBlocks(worker, currentBlocksOnTiers);
      processWorkerOrphanedBlocks(worker);
    }
    if (options.isSetConfigList()) {
      List<alluxio.wire.ConfigProperty> wireConfigList = options.getConfigList()
          .stream().map(alluxio.wire.ConfigProperty::fromThrift)
          .collect(Collectors.toList());
      for (BiConsumer<Address, List<ConfigProperty>> function : mWorkerRegisteredListeners) {
        WorkerNetAddress workerAddress = worker.getWorkerAddress();
        function.accept(new Address(workerAddress.getHost(), workerAddress.getRpcPort()),
            wireConfigList);
      }
    }

    registerWorkerInternal(workerId);

    LOG.info("registerWorker(): {}", worker);
  }

  @Override
  public Command workerHeartbeat(long workerId, Map<String, Long> usedBytesOnTiers,
      List<Long> removedBlockIds, Map<String, List<Long>> addedBlocksOnTiers,
      List<Metric> metrics) {
    MasterWorkerInfo worker = mWorkers.getFirstByField(ID_INDEX, workerId);
    if (worker == null) {
      LOG.warn("Could not find worker id: {} for heartbeat.", workerId);
      return new Command(CommandType.Register, new ArrayList<Long>());
    }

    synchronized (worker) {
      // Technically, 'worker' should be confirmed to still be in the data structure. Lost worker
      // detection can remove it. However, we are intentionally ignoring this race, since the worker
      // will just re-register regardless.
      processWorkerRemovedBlocks(worker, removedBlockIds);
      processWorkerAddedBlocks(worker, addedBlocksOnTiers);
      processWorkerMetrics(worker.getWorkerAddress().getHost(), metrics);

      worker.updateUsedBytes(usedBytesOnTiers);
      worker.updateLastUpdatedTimeMs();

      List<Long> toRemoveBlocks = worker.getToRemoveBlocks();
      if (toRemoveBlocks.isEmpty()) {
        return new Command(CommandType.Nothing, new ArrayList<Long>());
      }
      return new Command(CommandType.Free, toRemoveBlocks);
    }
  }

  private void processWorkerMetrics(String hostname, List<Metric> metrics) {
    if (metrics.isEmpty()) {
      return;
    }
    mMetricsMaster.workerHeartbeat(hostname, metrics);
  }

  /**
   * Updates the worker and block metadata for blocks removed from a worker.
   *
   * @param workerInfo The worker metadata object
   * @param removedBlockIds A list of block ids removed from the worker
   */
  @GuardedBy("workerInfo")
  private void processWorkerRemovedBlocks(MasterWorkerInfo workerInfo,
      Collection<Long> removedBlockIds) {
    for (long removedBlockId : removedBlockIds) {
      MasterBlockInfo block = mBlocks.get(removedBlockId);
      // TODO(calvin): Investigate if this branching logic can be simplified.
      if (block == null) {
        // LOG.warn("Worker {} informs the removed block {}, but block metadata does not exist"
        //    + " on Master!", workerInfo.getId(), removedBlockId);
        // TODO(pfxuan): [ALLUXIO-1804] should find a better way to handle the removed blocks.
        // Ideally, the delete/free I/O flow should never reach this point. Because Master may
        // update the block metadata only after receiving the acknowledgement from Workers.
        workerInfo.removeBlock(removedBlockId);
        // Continue to remove the remaining blocks.
        continue;
      }
      synchronized (block) {
        LOG.info("Block {} is removed on worker {}.", removedBlockId, workerInfo.getId());
        workerInfo.removeBlock(block.getBlockId());
        block.removeWorker(workerInfo.getId());
        if (block.getNumLocations() == 0) {
          mLostBlocks.add(removedBlockId);
        }
      }
    }
  }

  /**
   * Updates the worker and block metadata for blocks added to a worker.
   *
   * @param workerInfo The worker metadata object
   * @param addedBlockIds A mapping from storage tier alias to a list of block ids added
   */
  @GuardedBy("workerInfo")
  private void processWorkerAddedBlocks(MasterWorkerInfo workerInfo,
      Map<String, List<Long>> addedBlockIds) {
    for (Map.Entry<String, List<Long>> entry : addedBlockIds.entrySet()) {
      for (long blockId : entry.getValue()) {
        MasterBlockInfo block = mBlocks.get(blockId);
        if (block != null) {
          synchronized (block) {
            workerInfo.addBlock(blockId);
            block.addWorker(workerInfo.getId(), entry.getKey());
            mLostBlocks.remove(blockId);
          }
        } else {
          LOG.warn("Invalid block: {} from worker {}.", blockId,
              workerInfo.getWorkerAddress().getHost());
        }
      }
    }
  }

  @GuardedBy("workerInfo")
  private void processWorkerOrphanedBlocks(MasterWorkerInfo workerInfo) {
    for (long block : workerInfo.getBlocks()) {
      if (!mBlocks.containsKey(block)) {
        LOG.info("Requesting delete for orphaned block: {} from worker {}.", block,
            workerInfo.getWorkerAddress().getHost());
        workerInfo.updateToRemovedBlock(true, block);
      }
    }
  }

  @Override
  public Set<Long> getLostBlocks() {
    return ImmutableSet.copyOf(mLostBlocks);
  }

  /**
   * Creates a {@link BlockInfo} form a given {@link MasterBlockInfo}, by populating worker
   * locations.
   *
   * @param masterBlockInfo the {@link MasterBlockInfo}
   * @return a {@link BlockInfo} from a {@link MasterBlockInfo}. Populates worker locations
   */
  @GuardedBy("masterBlockInfo")
  private BlockInfo generateBlockInfo(MasterBlockInfo masterBlockInfo) throws UnavailableException {
    if (mSafeModeManager.isInSafeMode()) {
      throw new UnavailableException(ExceptionMessage.MASTER_IN_SAFEMODE.getMessage());
    }
    // "Join" to get all the addresses of the workers.
    List<BlockLocation> locations = new ArrayList<>();
    List<MasterBlockLocation> blockLocations = masterBlockInfo.getBlockLocations();
    // Sort the block locations by their alias ordinal in the master storage tier mapping
    Collections.sort(blockLocations, Comparator
            .comparingInt(o -> mGlobalStorageTierAssoc
                    .getOrdinal(o.getTierAlias()))
    );
    for (MasterBlockLocation masterBlockLocation : blockLocations) {
      MasterWorkerInfo workerInfo =
          mWorkers.getFirstByField(ID_INDEX, masterBlockLocation.getWorkerId());
      if (workerInfo != null) {
        // worker metadata is intentionally not locked here because:
        // - it would be an incorrect order (correct order is lock worker first, then block)
        // - only uses getters of final variables
        locations.add(new BlockLocation().setWorkerId(masterBlockLocation.getWorkerId())
            .setWorkerAddress(workerInfo.getWorkerAddress())
            .setTierAlias(masterBlockLocation.getTierAlias()));
      }
    }
    return new BlockInfo().setBlockId(masterBlockInfo.getBlockId())
        .setLength(masterBlockInfo.getLength()).setLocations(locations);
  }

  @Override
  public void reportLostBlocks(List<Long> blockIds) {
    mLostBlocks.addAll(blockIds);
  }

  @Override
  public Set<Class<? extends Server>> getDependencies() {
    return DEPS;
  }

  /**
   * Lost worker periodic check.
   */
  private final class LostWorkerDetectionHeartbeatExecutor implements HeartbeatExecutor {

    /**
     * Constructs a new {@link LostWorkerDetectionHeartbeatExecutor}.
     */
    public LostWorkerDetectionHeartbeatExecutor() {}

    @Override
    public void heartbeat() {
      long masterWorkerTimeoutMs = Configuration.getMs(PropertyKey.MASTER_WORKER_TIMEOUT_MS);
      for (MasterWorkerInfo worker : mWorkers) {
        synchronized (worker) {
          final long lastUpdate = mClock.millis() - worker.getLastUpdatedTimeMs();
          if (lastUpdate > masterWorkerTimeoutMs) {
            LOG.error("The worker {}({}) timed out after {}ms without a heartbeat!", worker.getId(),
                worker.getWorkerAddress(), lastUpdate);
            mLostWorkers.add(worker);
            mWorkers.remove(worker);
            WorkerNetAddress workerAddress = worker.getWorkerAddress();
            for (Consumer<Address> function : mWorkerLostListeners) {
              function.accept(new Address(workerAddress.getHost(), workerAddress.getRpcPort()));
            }
            processWorkerRemovedBlocks(worker, worker.getBlocks());
          }
        }
      }
    }

    @Override
    public void close() {
      // Nothing to clean up
    }
  }

  /**
   * Selects the MasterWorkerInfo from workerInfoSet whose host or related IP address
   * exists in addresses.
   *
   * @param addresses the address set that user passed in
   * @param workerInfoSet the MasterWorkerInfo set to select info from
   * @param workerNames the supported worker names
   */
  private Set<MasterWorkerInfo> selectInfoByAddress(Set<String> addresses,
      Set<MasterWorkerInfo> workerInfoSet, Set<String> workerNames) {
    return workerInfoSet.stream().filter(info -> {
      String host = info.getWorkerAddress().getHost();
      workerNames.add(host);

      String ip = null;
      try {
        ip = NetworkAddressUtils.resolveIpAddress(host);
        workerNames.add(ip);
      } catch (UnknownHostException e) {
        // The host may already be an IP address
      }

      if (addresses.contains(host)) {
        addresses.remove(host);
        return true;
      }

      if (ip != null) {
        if (addresses.contains(ip)) {
          addresses.remove(ip);
          return true;
        }
      }
      return false;
    }).collect(Collectors.toSet());
  }

  @Override
  public void registerLostWorkerFoundListener(Consumer<Address> function) {
    mLostWorkerFoundListeners.add(function);
  }

  @Override
  public void registerWorkerLostListener(Consumer<Address> function) {
    mWorkerLostListeners.add(function);
  }

  @Override
  public void registerNewWorkerConfListener(BiConsumer<Address, List<ConfigProperty>> function) {
    mWorkerRegisteredListeners.add(function);
  }

  /**
   * Class that contains metrics related to BlockMaster.
   */
  public static final class Metrics {
    public static final String CAPACITY_TOTAL = "CapacityTotal";
    public static final String CAPACITY_USED = "CapacityUsed";
    public static final String CAPACITY_FREE = "CapacityFree";
    public static final String WORKERS = "Workers";
    public static final String TIER = "Tier";

    /**
     * Registers metric gauges.
     *
     * @param master the block master handle
     */
    @VisibleForTesting
    public static void registerGauges(final BlockMaster master) {
      MetricsSystem.registerGaugeIfAbsent(MetricsSystem.getMetricName(CAPACITY_TOTAL),
          new Gauge<Long>() {
            @Override
            public Long getValue() {
              return master.getCapacityBytes();
            }
          });

      MetricsSystem.registerGaugeIfAbsent(MetricsSystem.getMetricName(CAPACITY_USED),
          new Gauge<Long>() {
            @Override
            public Long getValue() {
              return master.getUsedBytes();
            }
          });

      MetricsSystem.registerGaugeIfAbsent(MetricsSystem.getMetricName(CAPACITY_FREE),
          new Gauge<Long>() {
            @Override
            public Long getValue() {
              return master.getCapacityBytes() - master.getUsedBytes();
            }
          });

      for (int i = 0; i < master.getGlobalStorageTierAssoc().size(); i++) {
        String alias = master.getGlobalStorageTierAssoc().getAlias(i);
        MetricsSystem.registerGaugeIfAbsent(
            MetricsSystem.getMetricName(CAPACITY_TOTAL + TIER + alias), new Gauge<Long>() {
              @Override
              public Long getValue() {
                return master.getTotalBytesOnTiers().getOrDefault(alias, 0L);
              }
            });

        MetricsSystem.registerGaugeIfAbsent(
            MetricsSystem.getMetricName(CAPACITY_USED + TIER + alias), new Gauge<Long>() {
              @Override
              public Long getValue() {
                return master.getUsedBytesOnTiers().getOrDefault(alias, 0L);
              }
            });
        MetricsSystem.registerGaugeIfAbsent(
            MetricsSystem.getMetricName(CAPACITY_FREE + TIER + alias), new Gauge<Long>() {
              @Override
              public Long getValue() {
                return master.getTotalBytesOnTiers().getOrDefault(alias, 0L)
                    - master.getUsedBytesOnTiers().getOrDefault(alias, 0L);
              }
            });
      }

      MetricsSystem.registerGaugeIfAbsent(MetricsSystem.getMetricName(WORKERS),
          new Gauge<Integer>() {
            @Override
            public Integer getValue() {
              return master.getWorkerCount();
            }
          });
    }

    private Metrics() {} // prevent instantiation
  }
}


text:
class Image(object):
    """
    Model object. Represent an image.
    An image can have execution parameters, required capabilities and the node where it is executed.
    All of them are optional.
    """

    def __init__(self, name, engine, id='', parameters={}, capabilities={}, node=None):
        """
        Constructor of the model object.

        :param name: the name of the image. Mostly related to the VAL plugin.
        :type name: str
        :param id: the id of the executed image instance. Mostly related to the VAL plugin.
        :type id: str
        :param parameters: a dict with one or multiple execution parameters. Default empty dict.
        :type parameters: dict
        :param capabilities: a dict with one or multiple capabilities which are necessary for running the image. Default
                             empty dict.
        :type capabilities: dict
        :param node: the node where the image is executed. Default None which is equivalent to the current node.
        :type node: dict
        """

        self.id = id
        self.name = name
        self.engine = engine
        self.parameters = parameters
        self.capabilities = capabilities
        self.node = node

    def __iter__(self):
        yield 'id', self.id
        yield 'name', self.name
        yield 'engine', self.engine
        yield 'parameters', self.parameters
        yield 'capabilities', self.capabilities
        yield 'node', self.node

    @staticmethod
    def transform(data):
        """
        Static method to translate an image dict into a image model.

        :param data: a dict with image data
        :type data: dict
        :return: the translated image model, None if something goes wrong
        """
        if 'name' not in data or 'engine' not in data:
            return None
        return Image(
            name=data['name'],
            engine=data['engine'],
            id=data['id'] if 'id' in data else '',
            parameters=data['parameters'] if 'parameters' in data else {},
            capabilities=data['capabilities'] if 'capabilities' in data else {},
            node=data['node'] if 'node' in data else {}
        )

redpajama_set_name: RedPajamaGithub


text:
HomeShowsGoing Underground
Syria Special: The Siege of Aleppo & Munich Ceasefire (E306)
Published time: 13 Feb, 2016 13:15 Edited time: 13 Feb, 2016 13:16
Aleppo, Syria © Abdalrhman Ismail © Reuters
Afshin Rattansi goes underground on the Munich ceasefire and the siege of the largest city in Syria - Aleppo. Alastair Crooke, former MI6 agent, discusses what's the cause behind the ceasefire in Munich and to what extent Putin and Assad contributed to that progress. And we speak to Daily Mail columnist, Peter Oborne, to discuss his dispatch in Syria and what's behind the mainstream media's portrayal of the ISIS/Daesh threat in Syria. Plus we look at this week's PMQs.
Going Underground http://fb.me/GoingUndergroundRT
Going Underground https://www.youtube.com/user/GoingUndergroundRT
Going Underground on Twitter http://twitter.com/Underground_RT
Afshin Rattansi on Twitter http://twitter.com/AfshinRattansi
on Instagram http://instagram.com/officialgoingundergroundrt
on SoundCloud https://soundcloud.com/rttv/sets/going-underground

redpajama_set_name: RedPajamaCommonCrawl


xEdu acceleration program alumni companies are starting pilots with 24 schools in Hong Kong at the beginning of April with the support of HKEdCity platform. This is the first time ever that edtech products coming from the Nordics are trialled in schools of Hong Kong.
All of the companies Bomberbot, Mightifier and Seppo are from the first batch of xEdu startup accelerator. Their products focus on developing the students' 21st century skills, namely problem-solving, innovation and creativity, social skills, teamwork, health and wellness and ICT skills. The same skills are in the heart of the new Finnish curriculum, introduced last fall.
"What sets these products apart from any ordinary edtech solution, is the fact that there is a strong pedagogical background in all of them. The products have been granted the Kokoa Standard, which means they have undergone a rigorous evaluation by Finnish pedagogical experts and proven to promote the 21st century skills", comments Stuart Patton, Chairman of the Hong Kong FinnCham Education Committee, and co-founder of Polkuni HK representing the best Finnish Edu-products.
In December 2016, xEdu, Polkuni HK and Hong Kong Education City signed a memorandum of understanding which opens up the possibility for the startups to pilot Finnish solutions in Hong Kong schools.
The pilots will go on for one year, and the impact is being assessed throughout the project.


In the dataset properties Parameters page, change the mapping for the UserID query parameter to use the UserID report global object, as in: =Globals!UserID. You can also delete the UserID report parameter that was autogenerated by the dataset.
In the above example, the row or object would be hidden if the user's region was not Region A.


text:
Darwen Ramblers FC was an English association football club based in Darwen, Lancashire.

History

The club was originally called Hill-Houses and its first recorded match was against the Black Prince club of Little Harwood in December 1878; by this time the club had enough members for a second team which played the Black Prince reserves.

By 1881 the club had changed its name to Darwen Ramblers and rose in prominence in Lancashire, being considered one of the rising sides in Darwen; however there was competition from other sides such as Darwen itself, Lower Darwen, and Lower Chapel, all of whom had, unlike the Ramblers, entered the Lancashire Senior Cup.  The Ramblers entered the competition for its third instalment, being drawn against Irwell Springs in the first round, and surprisingly losing 6-3 having been 3-0 up.

Paradoxically the club had more success in the FA Cup than the Lancashire Cup; in 1882-83 the club beat South Shore and Haslingden Association to reach the third round of the FA Cup, where they lost to the eventual winners Blackburn Olympic, but in the Lancashire Cup they lost 4-3 at Padiham, having been 2-0 and 3-1 up.  The Ramblers protested the result on the basis that the winning goal came three minutes after the referee should have called for time; the protest was not successful.

That season however marked the only wins in the FA Cup for the Ramblers.  Their entries in the next two years saw them eliminated in the first round, although they were unlucky in 1883-84 to be drawn against the holders.  The 1883 game against Olympic was the first of that season's competition to be played, as Olympic offered Ramblers £10 and a return fixture to move the fixture up in the calendar, so that the Olympic players would be Cup-tied for the season.  However the Ramblers were not attractive opponents and the crowd was a mere 400.

The club remained prominent on the local scene in 1882-83 and 1883–84, including Preston North End among their opponents, and sent a representative to the Football Association AGM in 1883.  The club also finally won a tie in the Lancashire Cup, beating Blackburn West End in the first round in 1883-84, but a sign of the distance between the club and the professionals was demonstrated when they lost 4-0 in the second round to a Blackburn Olympic reserve side, as the Light Blues' first team was on a Scottish tour, playing Edinburgh University F.C. on the day of the tie.

Demise

By 1885-86, very few of the club's fixtures were attracting media attention.  The last recorded fixture was a 4-1 defeat at Wigan A.F.C. in the Lancashire Senior Cup.  The club did not pay its subscription to the Lancashire FA for the 1886-87 season and seems to have been wound up.

Notable players

 Sam Fish, future Darwen captain
 James Kenyon, future Darwen player

References

Defunct football clubs in England
Sport in Lancashire
Defunct football clubs in Lancashire

redpajama_set_name: RedPajamaWikipedia


Wandler's Mia Tote Bag is a study in crisp, clean lines in design. Dutch-designed and Italian-made out of the smoothest leather, the Mia Tote features multiple pockets within it's sleek silhouette. We love the winged edges that really make this tote stand out. Hold yours close by the short handle or go hands free by slipping it over your shoulder.
Tan calf leather exterior, interior colour coated, internal closing clasp.
Black calf leather exterior, interior colour coated, internal closing clasp.
Approximately measures; Depth 14cm, Height 32cm, Width 54.5cm.
Adjustable and detachable double shoulder straps and top handle, gold-tone hardware, hot stamped logo.
Rear slot pocket. Internal slip pocket and card slot.


text:
Hakuhodo DY music & pictures Inc.
Hakuhodo DY music & pictures Inc. is involved in a broad range of businesses including film distribution, production of Japanese films and animation, as well as sale of overseas programs. It's product line-up is also varied, with its new releases including "What Happened When I Shaved My Beard" and "I've Been Killing Slimes for 300 Years and Maxed Out My Level".
7F S-GATE Akasaka, 6-2-4 Akasaka, Minato-ku, Tokyo
Tomoe Ishii
International Sales Group
I've Been Killing Slimes for 300 Years and Maxed Out My Level
An at-home comedy about a powerful girl who doesn't work too hard!
After dying of overwork in the real world, I'm reincarnated as an immortal witch, and I spend 300 years enjoying a relaxing life. At some point, though, I end up at level 99!
All those years spent killing slimes to make the mon...
Scar On The Praeter
Tokyo. The Akatsuki Special District. This newly created special economic zone was fully controlled by the gigantic Sakishima Holdings conglomerate. Attempts by rival corporations to take advantage of the tax advantages and other regulatory benefits within the zone lead to the massive "Akatsuki Conf...
Goblin Slayer - Goblin's Crown
I'm not interested in saving the world. I only want to kill goblins. In a guild on the outskirts of civilization, there's an adventurer who's risen to silver rank (the third highest) doing nothing but slaying goblins… A new adventurer priestess find herself in trouble in her first party. The man who...
SHIROBAKO The Movie
The five members of the Kaminoyama High School anime club swore over a box of Hyoutan doughnuts that someday they would make an anime. After graduating, they all go on to work in different places in the anime industry.
After producing "Exodus!" and "Third Aerial Girls Squad", Aoi Miyamori begins to...
Talentless Nana
Psychics are sent to a school on an isolated island in the middle of the ocean, in order to fight a supposed "enemy of humanity". But a girl who transfers there is actually an assassin sent by the government to kill the psychics, who are the true "enemy of humanity!"
She'll have to use her brains...
Words Bubble Up Like Soda Pop
My 17th summer in a countryside city…
Cherry is a young boy who has trouble communicating with others, who always wears headphones so that nobody will talk to him. His hobby is putting the feelings he can't say aloud into his 'haiku', Japanese poem. Smile is a girl who always wears a mask to hide h...
The world has evolved into something different from Japan as we know it.
Traditional Japanese girls are expected to have "tank skills" as well as flower arrangement and tea ceremony skills, and every school has a "tank club".
Miho, a first-year at Matsue girls school, joins the feeble tank club ...
GRISAIA Phantom Trigger THE ANIMATION
Mihama Academy: A school set up by the government organization CIRS to train a new generation of special agents. Lost girls, torn from ordinary life by the myriad vicissitudes of fate, gather here to be trained in the art of the gun. Among them are four members of SORD, a special force set up to do ...
Drama (Series)
IRODUKU:The World in Colors
A girl meets boy story between Hitomi, a girl who lost her color, and Yuito Aoi, the boy who brought it back. An almost painfully pure love story. A story about youth told from multiple perspectives, including those of her grandmother Kohaku and the rest of her club. Through these experiences, hea...


text:
It's 'World Dracula Day' today and on the 27th May 1897, the Gothic horror novel "Dracula" by Bram Stoker was first published in London.
So the chat question today is: Do you have any favourite vampire films or books?
Head over to our upbeat chat forum page and share your answers!
This weeks Culture Vulture suggestions :
Target Margin Theater presents Magic In Plain Sight
A series of performances that reflects on this unusual year, celebrates the joy of gathering, and imagines the possibilities ahead of us! The three artists in residency for Magic in Plain Sight – Leonie Bell, Kaaron Briscoe, and LubDub Theatre Co – each read excerpts of their work, present rehearsal video, and lead interactive theatre exercises as they discuss the research and development of their upcoming productions.
27th May at 7.00 to 8.00 pm
https://www.eventbrite.co.uk/e/magic-in-plain-sight-with-target-margin-theatre-registration-152762357323?aff=ebdssbonlinesearch&keep_tld=1
Join Dr. Sue Brunning for her lecture Respect your Elders
Old Swords in Early Medieval England as part of the Flag Fen Archaeology Lectures. Dr. Brunning is Curator of European Early Medieval & Sutton Hoo Collections at the British Museum. She specialises in early Anglo-Saxon material culture with a particular focus on research interest in metalwork, beliefs and ritual, warrior culture, attitudes and world-views, and the life-histories of artefacts.
27th May at 7.00 pm
https://www.eventbrite.co.uk/e/respect-your-elders-old-swords-in-early-medieval-england-tickets-150746409569?aff=ebdssbonlinesearch
Abandon Normal Devices Festival
Free events including The Sea collapsed into the Pleasures of sand. The name of the river Mersey originates from the Old English 'Maere,' meaning 'boundary'. Boundaries and borders are sites of transition and transformation; liminal spaces where dimensions meet. Historically, in the brackish waters of the Mersey estuary—a space where fresh and saltwater meet—countless ships launched themselves toward the sea, animated by the Empire's desire for domination and its insatiable hunger for bodies, human and non-human.
27th May – 11th July.
https://www.andfestival.org.uk/events/pleasures-of-sand/
Photography talk with Alison Jackson
A multi award-winning artist, photographer and filmmaker who will present her recent Truth is Dead series featuring evocative photographs in which look-a-like doubles pose as public figures, celebrities and royals.
From Kim Kardashian to Donald Trump, these doppelgängers simulate intimate, and even exposed situations to raise questions about celebrity culture and the public desire for gossip. Thursday 27th May 6.30 to 7.30pm
https://www.eventbrite.co.uk/e/truth-is-dead-with-photographer-alison-jackson-tickets-150748738535
Royal Academy : be inspired and get creative
Suitable for both beginners and more experienced artist. A free event to join artist tutors in the Royal Academy for the opportunity to be inspired and get creative, using drawing materials you'll have at home.
Each Saturday morning session will be led by a different artist, and you're welcome to come into as many or as few as you'd like. All you'll need is a pencil and paper, with each session exploring different techniques and styles.
29th May 10.30 to 11.45am plus every Saturday in June.
https://www.royalacademy.org.uk/event/saturday-sketch-club?utm_source=wordfly&utm_medium=email&utm_campaign=AE_OnlineEventsRelease_d_Marketing_220421&utm_content=version_A&sourceNumber=636369
Cooking and dining in imperial Rome
A free ebook available to anyone.
https://www.gutenberg.org/files/29728/29728-h/29728-h.htm
Flame Painter, have a dabble with shapes and patterns, an online experiment
https://www.escapemotions.com/experiments/flame/index.php
Art Matters podcast: how Alfred Hitchcock created artful suspense
In the title sequence for Alfred Hitchcock's television series, Alfred Hitchcock Presents, the show opened with a sketch of the director that he drew himself. What comes to mind when you think of Hitchcock? Is it his iconic films? His status as a master of suspense? What about his love of art and design?
https://artuk.org/discover/stories/art-matters-podcast-how-alfred-hitchcock-created-artful-suspense?utm_source=Art+UK+Newsletter&utm_
Beginners calligraphy
https://restless.co.uk/leisure-and-lifestyle/learning/an-introduction-to-calligraphy/?utm_source=Community+Email&utm_medium=email&utm_campaign=21-05-06
Study Van Gogh Iris's at the Getty museum
https://blogs.getty.edu/iris/a-rare-opportunity-to-study-van-goghs-irises/?utm_medium
Thanks for listening best wishes to all!


Spencer Stone, whose summertime heroics in foiling a terrorist attack on a French train were recognized by President Barack Obama, has been promoted, the U.S. Air Force announced Saturday.
Stone was elevated to staff sergeant from airman 1st class during a spirited ceremony Friday at Travis Air Force Base in which officials cited his "heroic actions" in August.
The promotion, which takes effect Sunday, comes two weeks after the Sacramento native was released from UC Davis Medical Center, where he was treated for stab wounds from a late-night altercation in midtown. The suspects remain at large.
Stone, 23, and two childhood buddies have become media darlings since thwarting the would-be attack. Along with Anthony Sadler and Alek Skarlatos, Stone is credited with subduing a man armed with an AK-47 and Luger pistol on the Paris-bound train.
Skarlatos, a specialist in the Oregon National Guard, has become a regular on ABC's "Dancing With the Stars," and was honored as "Veteran of the Game" at Game 3 of the World Series at Citi Field in New York.
Sadler, a senior at Sacramento State University, has been celebrated by his peers and relayed his version of the attack on "The Tonight Show Starring Jimmy Fallon."
Standing beside Kings owner Vivek Ranadive, the trio was presented with NBA basketballs -- and lifetime supplies of pizza. Stone told a reporter that his recovery was going relatively well, adding "every day I get a little better."


A new stocking-sized gift idea for children that combines fun, education and development – child development chopsticks – is launching in the UK in October.
From Korea, CleverstiX are said to be easy to use, cool, stylish, high-quality and child-safe products for kids aged three years and over. They are available in versions featuring much-loved children's characters including Hello Kitty and Kung Fu Panda, and are endorsed by the Science Museum, London.
Thanks to the benefits of the patented ergonomic design (featuring strategically positioned finger and thumbs rings), CleverstiX can aid children while they eat, improve concentration, develop a handwriting grip, enjoy meal times, advance motor skills and learn chopstick control, the company claims.
Already scheduled to hit the shelves in the Science Museum Shop next month, CleverstiX are available now for wholesale orders to retailers, restaurants, nurseries, schools and other organisations.
Kevin North, founder of CleverstiX.com, said: "I discovered this amazing product during visits to South Korea, where its popularity in recent years has exploded.
"After originally bringing some home to the UK as gifts for friends and my own young son, I was astounded by the overwhelmingly positive feedback received from parents and children alike, which I am delighted to see has been echoed consistently through focus group and pre-launch user reviews.


About a Nut» Blog Archive » Badminton!
It's been a long time since I've exercise, or play badminton. In fact, apart from the pathetic attempt at jogging, the last time I exercised was probably when we played badminton.
So … badminton sessions resume again! Booked courts for last sat, this sat, and the sat to come. Boy, badminton courts are really hard to book. They are so popular.
Photos by Simon and his Motorola MilestoneXT720.
This entry was posted on Monday, September 13th, 2010 at 12:42 am and is filed under personal rants.	You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
I just played with LQ this past weekend!!!! So much fun!!!!! Yay, you're playing too!
Why the net sagging so much?
I saw on the booking site that the CC doesn't provide nets. I thought they were kidding, but they weren't. I bought a cheapo $8 net just in case, but didn't think we would actually need to use it. The string that came with it is too short!


Bubble-bursting: absolutely NO casual chatting about works in progress!
I decided to STOP talking about manuscripts I'm working on to my friends.
Chatting about the story (even if the feedback is positive and my friends are interested or excited), kind of "bursts the bubble", so to speak. I soak up any immediate gratification I get from people's interest and awe over my idea for a book when its better to JUST WRITE THE BOOK INSTEAD. Chatting about it makes me feel like I did something…and I didn't. It also releases my own excitement and motivation to get the words down so I end up just kind kind of lazily driiftng around in my lovely, fantastical ideas where they remain locked in their own world in my head when they should be getting written down or typed out word for word.
So I accepted that the only thing to do is to write that book.
No more talking. Talking about the book isn't writing it. Hold all that pressure in, keep the surface tension, maintain the bubble. It can't be done until its written first.
Its way more exciting to give my friends and readers a wonderful book, as opposed to just telling them about it.
Posted on October 19, 2014 by S.T. Rucker.	This entry was posted in Journal, The Porcupine's Dilemma and tagged bubble bursting, creative writing, independent authors, writer problems, writing, writing advice. Bookmark the permalink.
All creative work by S.T. Rucker is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.


text:
Bhumi Pednekar on horror film Bhoot Part One: The Haunted Ship — Haven't explored this genre before
Bhumi Pednekar will soon be seen opposite Vicky Kaushal in Dharma Productions' horror project Bhoot Part One — The Haunted Ship. The first instalment of the franchise will be directed by Bhanu Pratap Singh. Singh has earlier worked with Shashank Khaitan on Humpty Sharma Ki Dulhania (2014) as an assistant. The makers had released a poster of the film on 10 June.
Speaking about stepping into the horror genre and working with Kaushal, Pednekar said in a statement, "Vicky is one of the most talented actors of today and it's lovely working with him. It's a genre that both of us haven't explored before but I was quite thrilled to experiment with. As an actor, I love to experiment, love to take risks."
Bhumi Pednekar. Image from Facebook/@BhumiPednekarOfficial
Pednekar is known for her eclectic choices in films like her debut Dum Laga Ke Haisha (2015), which was followed by the drama Toilet: Ek Prem Katha (2017), Shubh Mangal Saavdhan (2017), Netflix's Lust Stories (2018) and her latest release, the dacoit drama Sonchiriya.
She will be seen next in Anurag Kashyap's Saand Ki Aankh, along with Taapsee Pannu. The duo will essay the roles of India's oldest sharpshooters Chandro and Prakashi Tomar in the biographical drama. Pednekar is also a part of Pati, Patni aur Woh, a remake of BR Chopra's iconic comedy of the same name. She will share the screen space with Kartik Aaryan and Ananya Panday. She will also be seen with Konkona Sensharma in Alankrita Shrivastava's Dolly, Kitty Aur Chamakte Sitaare, and Karan Johar's period drama Takht.
tags: Ananya Panday , Anurag Kashyap , Bhanu Pratap Singh , Bhoot – Part One: The Haunted Ship , Bhumi Pednekar , Bollywood , Buzz Patrol , BuzzPatrol , Dharma Productions , Karan Johar , Kartik Aaryan , pati patni aur woh , saand ki aankh , Shashank Khaitan , Taapsee Pannu , Vicky Kaushal
Bhoot: Part One - The Haunted Ship — Ashutosh Rana joins cast of Vicky Kaushal, Bhumi Pednekar's horror film
Taapsee Pannu takes a dig at Rangoli Chandel, asks Varun Dhawan to name her in Saand Ki Aankh tweet
Bhumi Pednekar, Taapsee Pannu share behind-the-scenes stills from the sets of Saand Ki Aankh
1Bhumi Pednekar on horror film Bhoot Part One: The Haunted Ship — Haven't explored this genre before


Made this for my teenage daughter who loves the little mermaid. went to my nearest fabic store and purchased tulle for the tale and for the skirt part a fish looking material and used one of her skirts for the pattern..now for the top we purchased a purple bandeau and glued the sea shells (ordered them on line). paint them and glued on. thats much it...OH and of course you need to sew all the skirt parts and tail together and there you have it.
This is Simply Amazing! Great Job! I'd Have No Problem Paying For Something Like This!
Amazing! I would totally wear this!... If I had the body for it.


text:
F-35B Lightning II Joint Strike Fighter STOVL Variant
United States Marine Corps, Royal Air Force, Royal Navy and Italian Navy
Maiden Flight
Empty Weight
14,651kg
Maximum Take-off Weight
1 x Pratt & Whitney F135 turbofan engine rated at 125kN of dry thrust
1,960km/h
F-35B is designed and being developed by Lockheed Martin, Image courtesy of Lockheed Martin Corporation.
The F-35B can fly at a maximum speed of 1,960km/h, Image courtesy of Lockheed Martin Corporation.
Cutaway model of F-35B integrated with LiftFan propulsion system, Image courtesy of Lockheed Martin Corporation.
F-35B takes off from the USS Wasp aircraft carrier as part of the ship trials, Image courtesy of Lockheed Martin Corporation.
The F-35B Standard Take-off and Vertical Landing (STOVL) is a single-engine, fifth generation fighter aircraft designed and developed by Lockheed Martin. It is the first aircraft to combine stealth technology with STOVL capabilities and supersonic speeds.
The F-35B will supersede the F/A-18 Hornet and AV-8B Harrier II fighter aircraft currently in service with the United States Marine Corps (USMC). It will also replace GR7, GR9 and Sea Harrier aircraft deployed in the fleet of the Royal Navy and Royal Air Force.
Design of the JSF F-35B STOVL variant
The critical design review of the F-35B was completed in October 2006. The tricycle type retractable undercarriage design allows the aircraft to take-off from and land on the deck of small naval ships, unimproved airstrips, rough airfields and roads.
The aircraft is fitted with a refuelling probe on the right side of the front fuselage to carry out mid-air refuelling during combat missions. The weapon loads and cockpit layout of the F-35B are similar to those of the F-35 Joint Strike Fighter (JSF).
Development of the F-35B Joint Strike Fighter
The development of F-35B began in November 2003. The aircraft was rolled out in December 2007. The maiden flight of the first F-35B prototype took place in June 2008. The low rate initial production (LRIP) contract for six F-35B STOVL aircraft was placed in July 2008. The second prototype achieved its first flight in February 2009.
The F-35B accomplished its hover capability during a flight test that took place at Naval Air Station Patuxent River in March 2010. It accomplished supersonic speeds in June 2010. The shipboard testing of the aircraft on the flight deck of the USS Wasp (LHD-1) aircraft carrier was completed in October 2011. The first two F-35Bs were delivered to the USMC in January 2012.
The assembly of the UK's first production F-35B aircraft, designated BK-1, was completed in November 2011. The maiden flight of the BK-1 took place in April 2012.
F-35B STOVL engines and propulsion
The F-35B STOVL is powered by a single Pratt & Whitney F135 afterburner turbofan engine rated at 125kN of dry thrust. The engine can produce 191.3kN of thrust afterburner. It is the successor of F119-PW-100 turbofan engine. It is equipped with full authority digital engine control, a gearbox, and health and usage monitoring system.
A shaft-driven LiftFan propulsion system built by Rolls-Royce is incorporated at the aft of F-35B's cockpit to accomplish the STOVL capabilities. Doors fitted above and below the vertical fan open as the fin spins up for vertical lift of the aircraft. The counter-rotating LiftFan produces more than 20,000lb of thrust with the help of the gas turbine.
Three-bearing swivelling exhaust nozzle is appended by two roll control ducts on the inboard section of the wing. The engine combined with the vertical LiftFan renders the requisite STOVL capability.
The length and diameter of the engine are 5.5m and 1.3m respectively. The inlet diameter is 1.1m.
The F-35B can fly at a maximum speed of 1,960km/h. The combat radius and maximum range of the aircraft are 833km and 1,667km respectively.
The F-35B is fitted with a 25mm GAU-22A Gatling cannon which has 220 rounds per gun of firing capacity. It has two internal weapon pods and four external underwing hardpoints to expand its mission lethality.
The aircraft can carry 6,803kg of weaponry payload. It is equipped with AIM-120C AMRAAM medium range air to air missiles, air to surface missiles, two GBU-32 JDAM guided bombs, six GBU-38 bombs and munitions dispensers.
Countermeasures and radars
The F-35B is equipped with AN/APG-81 Active Electronically Scanned Array (AESA) multi-functional radar built by Northrop Grumman. It also houses AN/AAQ-37 Distributed Aperture System (DAS), Barracuda AN/ASQ-239 electronic warfare system, Multifunction Advanced Data Link (MADL) communication system and missile warning system.
F-35B STVOL orders and deliveries
Customer orders of the F-35B include USMC (340) and Italian Navy (22). The UK ordered two F-35Bs in 2009. The third F-35B was ordered by the UK Government in January 2010. The UK Ministry of Defence plans to procure up to 138 F-35Bs for the Royal Air Force and the Royal Navy.
F-35 Lightning II Joint Strike Fighter (JSF)
Overview of the F-35 Lightning II joint strike fighter (JSF) programme being developed by Lockheed Martin Aeronautics Company for the US Air Force, Navy and Marine Corps and the UK Royal Navy.
F-35C Joint Strike Fighter CATOBAR carrier variant
F-35C CATOBAR (Catapult Assisted Take Off Barrier Arrested Recovery) is an advanced fifth generation fighter carrier variant designed and being manufactured by Lockheed Martin Corporation for the US Navy and the UK Royal Navy.
Global Military Aircraft Market 2011-2021
This project forms part of our recent analysis and forecasts of the global Military Aircraft market available from our business information platform Strategic Defence Intelligence. For more information click here or contact us: EMEA: +44 20 7936 6783; Americas: +1 415 439 4914; Asia Pacific: +61 2 9947 9709 or via email.


34-inch Extra Wide Tension Mount Pet Gate is rated 4.9 out of 5 by 15.
Rated 5 out of 5 by Del3030 from Perfect Pet Gate We are actually using this on our covered Lanai so Our dog can enjoy being outside without having to worry too much about her getting out. The Gate is beautiful and solid. I'm so glad we bought this. Only small issue would be the instructions for assembly aren't very good at all. But we just pulled up a YouTube how-to video and got it up fine. Still give 5 stars!!
Rated 5 out of 5 by Safegates in Colorado from Durable with great looks We purchased 3 of these gates 3 years ago with 2 dogs and 3 children under the age of 4 yrs. the gates have seen a lot of use. They still function as well as the first day we installed them. Our 4 yr. old figured out how to open the gate but the 2 yr. old twins cannot open it on their own. Very useful for keeping toddlers off stairs.
Rated 4 out of 5 by Marimari61 from Looks great + functions well! I purchased this gate recently for my daughter's home, to contain her dog to one area of the house. It was relatively easy to install, but I suggest 2 people to do it. The door swings close + latches automatically after passing through it. No more climbing over expandable gates! It looks great + functions perfectly!
Rated 5 out of 5 by BCR410 from Perfect for what I needed I can't express how much I love this gate. The quality is solid, and looks really nice. For the price, it exceeded my expectations!
Rated 5 out of 5 by Nikki22 from Finally...a pretty gate! This gate functions as well as it looks! Looked forever to find a pretty gate that matched our newly renovated home & this is it! Get compliments every time someone is over.
Rated 5 out of 5 by whosit from Beautiful It works great as a pet gate and looks elegant - not at all like a typical pet gate.
Rated 5 out of 5 by Sharon 1 from Great gate I have the gate in between my Kitchen & Dining room. It keeps the dogs(12 yr.old Westie and visiting 4month old untrained Beagle) out of the carpeted areas. It was easy to install and I love the walk through gate. Highly recommend..
Rated 5 out of 5 by Millieberta from Very Pleased We purchased the gate for our front entrance because one of our dogs is a runner. It matches our door well and and easily opens to allow entrance and exit from the house. I highly recommend it.
How wide does the gate expand to? We have a really open kitchen that leads to the family room. I believe it is at least 8 to 9 feet wide! What gate solution, if any would you recommend?
Thank you for your interest in the 34-inch Extra Wide Tension Mount Pet Gate. This gate extends between 28-1/2" - 42"W. This would not fit your space, you may want to look into something like our Six-panel Hardwood Pet Gate (item #62665).
Does this gate automatically close or do I have the option of leaving it open if I want to?
Thank you for your interest in the 34-inch Extra Wide Tension Mount Pet Gate. This gate does have an auto return lock as well as a manual lock.
Thank you for your interest in the 34-inch Extra Wide Tension Mount Pet Gate. This gate expands to 42" so it should fit your doorway.
Thank you for your interest in the 34-inch Extra Wide Tension Mount Pet Gate. This only opens to the 42". We apologize for the inconvenience.
Is this 42 inches wide as is or do I needto buy attachments?
Thank you for your interest in the 34-inch Extra Wide Tension Mount Pet Gate. The 42"W is how the gate comes.
Thank you for your interest in the 34-inch Extra Wide Tension Mount Pet Gate. If your gate is moving when the door is opened and shut, make sure that you have the tension mounts completely tightened and secure enough to hold the gate in place. If you need further assistance, please call in to our Product Specialist Department at 800-537-8484 and they can assist you with this.
How high is this gate?
Thank you for your interest in the 34-inch Extra Wide Tension Mount Pet Gate. This gate is 34" tall.
Does this gate have a spring so that it automatically closes?  I'm concerned my kids won't close it after opening and will defeat the purpose.


text:
Q: Cannot connect to SFTP uding apache camel I am using Apache Camel 2.17.0 for picking a file from SFTP location. Its a Springboot application. I can see that after SFTP call, the SFTP user is auto locked and the error I get is, cannot connect to sftp. Is the following error because of lockout issue? Please help.
org.apache.camel.component.file.GenericFileOperationFailedException: Cannot connect to sftp://GATEWAY:22/inbox?username=USERNAME&password=#####/"
    at org.apache.camel.component.file.remote.SftpOperations.connect(SftpOperations.java:146) ~[camel-ftp-2.17.0.jar:2.17.0]
    at org.apache.camel.component.file.remote.RemoteFileConsumer.connectIfNecessary(RemoteFileConsumer.java:203) ~[camel-ftp-2.17.0.jar:2.17.0]
    at org.apache.camel.component.file.remote.SftpConsumer.doStart(SftpConsumer.java:52) ~[camel-ftp-2.17.0.jar:2.17.0]
    at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext.startService(DefaultCamelContext.java:3269) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRouteConsumers(DefaultCamelContext.java:3563) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext.doStartRouteConsumers(DefaultCamelContext.java:3499) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext.safelyStartRouteServices(DefaultCamelContext.java:3429) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRoutes(DefaultCamelContext.java:3197) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3053) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:175) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2848) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2844) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:2867) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:2844) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:2813) [camel-core-2.17.0.jar:2.17.0]
    at org.apache.camel.spring.boot.RoutesCollector.onApplicationEvent(RoutesCollector.java:116) [camel-spring-boot-2.17.0.jar:2.17.0]
    at org.apache.camel.spring.boot.RoutesCollector.onApplicationEvent(RoutesCollector.java:41) [camel-spring-boot-2.17.0.jar:2.17.0]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:166) [spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138) [spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:381) [spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:335) [spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:855) [spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:140) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) [spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
    at tripRecommenderPackage.MainApplication.main(MainApplication.java:10) [classes/:na]
Caused by: com.jcraft.jsch.JSchException: SSH_MSG_DISCONNECT: 11 Account is locked
    at com.jcraft.jsch.Session.read(Session.java:996) ~[jsch-0.1.53.jar:na]
    at com.jcraft.jsch.UserAuthKeyboardInteractive.start(UserAuthKeyboardInteractive.java:77) ~[jsch-0.1.53.jar:na]
    at com.jcraft.jsch.Session.connect(Session.java:463) ~[jsch-0.1.53.jar:na]
    at org.apache.camel.component.file.remote.SftpOperations.connect(SftpOperations.java:118) ~[camel-ftp-2.17.0.jar:2.17.0]
    ... 32 common frames omitted

A: Yep. Looks like the account is locked. You can validate by sftp/ssh to the remote server manually.

redpajama_set_name: RedPajamaStackExchange


text:
Protected Lands
History of MI Conservation
Land Conservancies
Find Your Conservancy
Landowner Options
Michigan Model
Funding/Partnership Options >
Michigan DNR
MI Dept. of Agriculture
Taking Action // The Path Ahead
Places Create Stories
protectMI
Passion & Purpose
Getting Outside During a Pandemic
Adventure Hub
What is a Land Conservancy?
Land conservancies, also known as land trusts, are community-based, nonprofit organizations dedicated to the permanent protection and stewardship of natural and working lands for the public good.
Land conservancies are positioned to act swiftly and professionally to help landowners and communities protect the places important to us all—open spaces that define our sense of place, connect us to the natural world, and provide real services such as water quality protection, wildlife habitat, outdoor recreation, and sources of food and timber.
How does a Land Conservancy Work?
Land conservancies are suited better than any other organization to safeguard Michigan's natural beauty and the conservation values of our most important lands. To do this, land conservancies use the following suite of tools to protect and steward land forever:
Nature preserves or sanctuaries - Lands are acquired through donation or purchase to be used as a nature preserve or sanctuary. Often, these lands are open to the general public to visit and enjoy.
Conservation easements - A voluntary legal tool that allows the land to remain in private ownership but permanently limits development to protect the conservation values of the property. For more information visit: Conservation options for landowners.
Government assists - Conservancies often help local communities or the State of Michigan acquire public parkland and open space. Assistance can range from grant writing support to leading fundraising campaigns.
Stewardship - For the lands that are owned and managed by conservancies or for the conservation easements they hold, stewardship is the term used for ongoing management and monitoring to protect the conservation values of those properties.
Education - Whether providing education to landowners about conservation options or engaging community members in the stewardship of natural areas, conservancies educate people about the values of the natural environment.
Heart of the Lakes strengthens the collective efforts of organizations dedicated to the conservation of Michigan's environmentally and economically significant land and water. We provide leadership, innovative ideas, and advocate for smart public policy for the benefit of our communities and for generations to come.
Stay in the know - Subscribe to our monthly newsletter!
All Subscribers
Heart of the Lakes
Heart of the Lakes is a statewide organization that concentrates and strengthens the efforts of Michigan's land conservation community. Founded by Michigan's land conservancies, Heart of the Lakes does what no individual organization can do on its own-- unites them under the common goal of protecting Michigan's land.
P.O. Box 1128 Bay City, MI 48706


Enter the bank and see if you have what it takes to win the top prize worth more than €98,000 that lurks within its vault in video slot, Break da Bank Again. Designed with the VIP player in mind, this slot offers wilds, a gamble mode and free spins. Play for free or for real money, with bets ranging from €0.01 to €22.50 per spin.
Want to strike it rich? Then you'll need to enter the vault. Match three or more vault scatter symbols to win up to 25 free spins. Break da Bank Again wilds can substitute for any regular symbol, and come with a x5 multiplier during regular play, and a x25 multiplier during free spins. Boost your winnings by predicting the correct color or suit of the next card in the gamble mode. Match three or more amethysts to win up to €375.


I Hope You're a Fathead! – .
I Hope You're a Fathead!
Our brain is one of our most important organs. It must last us a lifetime! Sadly, many folk's brains are heading down the path of Alzheimer's due to lack of the right essential fatty acids for brain health.
As you know, the digestive tract is the second brain. It talks to the brain and the brain talks back. Actually, the conversation is more gut talking to brain than vice versa. But the brain needs particular essential fats.
If one has had their gallbladder removed or has issues with pancreatic function-both impair absorption of these fatty acids, so he/she wants help with absorption of fat soluble nutrients.
As we get older, it becomes more important to get help with memory breaking down. One of the reasons for this is, over time, we accumulate more chemical toxins that can affect brain function.
So remember, you want to be a fathead with the right fats keeping the brain in good shape!
Get in touch and we'll show you how to have a brighter brain!
← Where Your Immune System Lives!


Chuck proudly served in the Army National Guard from 1966-1972. Chuck received his professional training from MATTS in CO. His on-the-job training he received in Torrington, WY; Billings, MT; and Cut Bank, MT. During his employment at Big Sky Body Shop in Billings, MT he attended college full time at Eastern Montana College. He then acquired Newman's Body Shop, now Chuck's Paint and Body, in Cut Bank. Chuck has since expanded his operation to include Tire sales and service, Radiator repair and service, Brakes, Shocks, Alignments, General Maintenance and oil changes. He has provided quality workmanship and friendly customer service since 1974.
When Chuck is not hard at work at the shop he can be found enjoying a round of golf at his golf course nestled near Glacier National Forrest.
Heather moved to Cut Bank with her family in 2015 from Nashville, TN. She is currently the Office Manager, Accounts Receivables Representative and all around shop mom. Heather has owned her own businesses in the Washington, DC area, been a insurance agent, worked in advertising and country music while in Nashville.
Heather is committed to ensuring our customers have a positive experience from greeting to completed repair. She truly believes in service with a smile. Please contact her today to schedule a estimate or repair appointment.


Every single member from our higher effectiveness product sales staff values customers' requires and organization communication for Pvc Sheet For Advertisement , PVC Sheet for Advertisement , PVC Transparent Sheet for Advertisement , dependant on the faith of expert quality & all over the world provider.
"Our business puts emphasis to the management, the introduction of talented personnel, and the construction of team building, striving hard to improve the standard and liability consciousness of staff members. Our corporation successfully attained IS9001 Certification and European CE Certification of Pvc Sheet For Advertisement , PVC Sheet for Advertisement , PVC Transparent Sheet for Advertisement , Besides strong technical strength we also introduce advanced equipment for inspection and conduct strict management. All the staff of our company welcome friends both at home and abroad to come for visits and business on the basis of equality and mutual benefit. If you are interested in any of our items please feel free to contact us for quotation and product details.