'Close (cancel) spider and clear all its outstanding requests'

def close_spider(self, spider, reason='cancelled'):

    slot = self.slot
    if slot.closing:
        return slot.closing
    logger.info('Closing    spider    (%(reason)s)', {'reason': reason}, extra={'spider': spider})
    dfd = slot.close()
    def log_failure(msg):
        def errback(failure):
            logger.error(msg, exc_info=failure_to_exc_info(failure), extra={'spider': spider})
        return errback
    dfd.addBoth((lambda _: self.downloader.close()))
    dfd.addErrback(log_failure('Downloader    close    failure'))
    dfd.addBoth((lambda _: self.scraper.close_spider(spider)))
    dfd.addErrback(log_failure('Scraper    close    failure'))
    dfd.addBoth((lambda _: slot.scheduler.close(reason)))
    dfd.addErrback(log_failure('Scheduler    close    failure'))
    dfd.addBoth((lambda _: self.signals.send_catch_log_deferred(signal=signals.spider_closed, spider=spider, reason=reason)))
    dfd.addErrback(log_failure('Error    while    sending    spider_close    signal'))
    dfd.addBoth((lambda _: self.crawler.stats.close_spider(spider, reason=reason)))
    dfd.addErrback(log_failure('Stats    close    failure'))
    dfd.addBoth((lambda _: logger.info('Spider    closed    (%(reason)s)', {'reason': reason}, extra={'spider': spider})))
    dfd.addBoth((lambda _: setattr(self, 'slot', None)))
    dfd.addErrback(log_failure('Error    while    unassigning    slot'))
    dfd.addBoth((lambda _: setattr(self, 'spider', None)))
    dfd.addErrback(log_failure('Error    while    unassigning    spider'))
    dfd.addBoth((lambda _: self._spider_closed_callback(spider)))
    return dfd
