LINUX.ORG.RU

python удалить файл асинхронно

 ,


1

3

второй день изучаю питон.
есть у меня директория, куда падают файлики и файлики нужно после прочтения сжечь удалить
но возникают ситуации, когда те, кто файлики пишут - тупят и мне нужно делать таймаут перед повторной попыткой удалить
дело в том, что time.sleep() тормозит весь поток и я решил что поможет threading

import threading
import time

some_path = '/foo/bar'

def delete_file (arg, count=1):
	print str(count)+ ' try  delete ' + some_path
	time.sleep(1)
	if count < 10:
		count += 1
		recall = threading.Thread(target=delete_file, args=[arg, count])
		recall.start()
		return 1
	else:
		print 'too many tries'
		return 1

delete_file(some_path)

есть ли best practices по удалению файликов?

Сделай класс, в который будут отдаваться имена файлов для удаления. Класс будет по таймауту пробегать по файлам и пытаться их удалить. Потоков не нужно, слипов не нужно.

panter_dsd ★★★★ ()
Ответ на: комментарий от system-root

Откуда угодно. Почти любой UI подразумевает эвентлуп, например.

Корутины в 2.7 всегда были, там нет только yield from (который абузят в asyncio), но trollius обходится обычным yield и это даже не говоря о twisted. Хотя нафиг тебе всё это?

x3al ★★★★★ ()
Ответ на: комментарий от panter_dsd

Зачем «по таймауту» пробегать? Простейшая очередь, на жабе выглядело бы примерно так:

class Trash {

    // Singleton trash
    public static final Trash instance = new Trash();

    // Trash box content
    private Vector<String> files;

    private Trash() { files = new Vector<String>(); }

    public synchronized void put(String filename) {
        if (!files.contains(filename)) files.add(filename);
        for (int i=files.size-1;i>=0;i--) {
            File f = new File(files.elementAt(i));
            // Is this a file?
            if (f.isFile()) {
                // Yes. Try to remove
                if (f.delete()) {
                    // Removed. Drop it out of queue
                    files.removeElement(i);
                } else {
                    System.err.println("Can't drop "+files.elementAt(i)+" will retry later");
                }
            } else {
                // Not a file. Drop it out from queue.
                files.removeElement(i);
            }
        }
    }
}
...
trash.put("/tmp/aaa");
...
trash.put("/etc/passwd");
...

Nastishka ★★★★★ ()
Ответ на: комментарий от Nastishka

Зачем жаба? Простейшая очередь удаления на python'е выглядит примерно так:

import os, threading, time

def remove_file(fpath):
    for c in xrange(10):
        try:
            os.remove(fpath)
            break
        except:
            pass
        time.sleep(1)
    else:
        print 'too many tries for %s' % fpath

for fpath in some_files_list:
    t = threading.Thread(target=remove_file, args=(fpath,))
    t.start()
ximeric ()
Ответ на: комментарий от x3al

То был второй вариант, сначала-то было так:

import os, Queue, threading, time

Q = Queue.Queue()

def remove_file():
    while True:
        fpath = Q.get()
        for c in xrange(10):
            try:
                os.remove(fpath)
                break
            except:
                pass
            time.sleep(1)
        else:
            print 'too many tries for %s' % fpath

t = threading.Thread(target=remove_file)
t.start()

for fpath in some_files_list:
    Q.put(fpath)

И здесь точно используется объект типа «очередь».

ximeric ()
Ответ на: комментарий от Nastishka

Ну да. А сообщение о том, что удалилось/не удалилось — эвент. Цикл, в котором всё это удаляется — эвентлуп по сути.

Конечно, если параллельно с удалением не выполняется ничего блокирующего — второй поток нафиг не нужен, всё делается одним с эвентлупом.

Ну и само удаление — блокирующее обычно, особенно на удалённых ФС. Но в питоне же есть неблокирующий IO.

x3al ★★★★★ ()
Последнее исправление: x3al (всего исправлений: 1)
Ответ на: комментарий от ximeric

спасибо, я просто не знал об xrange.
хоть создание целого треда для удаления файла и оверхед, но код с threading пока смотрится чище и лаконичнее, чем всё, что можно нагуглить асинхронного.
по мере изучения конечно перепишу. а пока «и так сойдёт»

system-root ★★★★★ ()
Ответ на: комментарий от system-root

но код с threading пока смотрится чище и лаконичнее, чем всё, что можно нагуглить асинхронного.

...на эрланг асинхронное ещё более лаконичнее

anonymous ()
Ответ на: комментарий от anonymous

ага, только то что я пишу уже работает на node.js и доставляет кучу проблем с доставкой кода пользователям.
эрланг из той же оперы. местные админы повесятся поддерживать на винде

system-root ★★★★★ ()
Ответ на: комментарий от system-root

Пожалуйста.

Вообще, советовал бы обратить внимание на дельное предложение Nastishka (14.04.2015 21:01:57) и x3al (14.04.2015 21:13:11). Как я понял, в обсуждаемом ими варианте можно обойтись без потоков, с очередью удаляемых файлов. Пример к этому приводить не буду - что-то программист должен реализовывать сам... ;-)

Мои примеры с потоками были из-за того, что в исходном варианте упоминались потоки (по-мне, правда, достаточно странное использование).

ximeric ()
Ответ на: комментарий от system-root

Сравнил эрланг с нодой - совершенно разные вещи.

На винде не приходилось запускать - тут no comments.

anonymous ()
Ответ на: комментарий от system-root

Они существуют?

тут недавно была тема эта поднята тема, по поводу того, существуют ли программисты-дегенераты, которые выбирают язык и технологию, исходя из потребностей одминов и секретуток. Пришли к выводу, что не существуют. Значит ошиблись.

PS С чего ты вообще взял, что одмину нужно что-либо, кроме UI? Нахер ему влезать в твое приложение? Ты проблем на свою жопу ищешь?

anonymous ()

что time.sleep() тормозит весь поток и я решил что поможет threading

То есть, в хваленом пистоне нет асинхронности???!!! facepalm:) А как же, так получилось? Ведь говорят, на нем туева хуча серверного кода написано. Это возможно вообще, при сколько-нибудь значительных нагрузках? Или на нем только детсадовские поделия можно писать?

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.