def _drain(self, cycles=None):
        log.info("Now draining...")
        if not cycles:
            log.info("No cycle count, the pipeline may be drained forever.")
        if self.calibration:
            log.info("Setting up the detector calibration.")
            for module in self.modules:
                module.detector = self.calibration.get_detector()
        try:
            while not self._stop:
                cycle_start = timer()
                cycle_start_cpu = process_time()
                log.debug("Pumping blob
                self.blob = Blob()
                for module in self.modules:
                    if self.blob is None:
                        log.debug(
                            "Skipping {0}, due to empty blob.".format(
                                module.name
                            )
                        )
                        continue
                    if module.only_if and not module.only_if.issubset(set(
                            self.blob.keys())):
                        log.debug(
                            "Skipping {0}, due to missing required key"
                            "'{1}'.".format(module.name, module.only_if)
                        )
                        continue
                    if (self._cycle_count + 1) % module.every != 0:
                        log.debug(
                            "Skipping {0} (every {1} iterations).".format(
                                module.name, module.every
                            )
                        )
                        continue
                    if module.blob_keys is not None:
                        blob_to_send = Blob({
                            k: self.blob[k]
                            for k in module.blob_keys
                            if k in self.blob
                        })
                    else:
                        blob_to_send = self.blob
                    log.debug("Processing {0} ".format(module.name))
                    start = timer()
                    start_cpu = process_time()
                    new_blob = module(blob_to_send)
                    if self.timeit or module.timeit:
                        self._timeit[module]['process'] \
                            .append(timer() - start)
                        self._timeit[module]['process_cpu'] \
                            .append(process_time() - start_cpu)
                    if module.blob_keys is not None:
                        if new_blob is not None:
                            for key in new_blob.keys():
                                self.blob[key] = new_blob[key]
                    else:
                        self.blob = new_blob
                self._timeit['cycles'].append(timer() - cycle_start)
                self._timeit['cycles_cpu'].append(
                    process_time() - cycle_start_cpu
                )
                self._cycle_count += 1
                if cycles and self._cycle_count >= cycles:
                    raise StopIteration
        except StopIteration:
            log.info("Nothing left to pump through.")
        return self.finish()