Programming

ネットワークファイルへの stat() は、嘘をつかれることがあるよ!!

ネットワークファイル周りは結構地雷がたくさんあって、これも今年私がドハマりしたものです。
私が確認しているのはWindows7+Windows Server の組み合わせのみで XP などでは起きない症状ですが、ネットワーク上にファイルを作成/削除してもどこかでキャッシュが聞いているようで、数秒間はstat() が嘘情報を返すというものがあります。


import os
import time
import sys
import ctypes


def CreateHardLink(src, dest):
    if os.path.exists(dest):
        print 'file exist'
        raise FileExistError

    CreateHardLinkW = ctypes.windll.kernel32.CreateHardLinkW
    CreateHardLinkW.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_int]

    ret = CreateHardLinkW(dest, src, 0)
    if ret ==0:
        print ctypes.FormatError()
        print src
        print dest

        raise PlatformError

def clearData():
    for i in range(10):
        f = os.path.join(d, r'%s\%03d.txt' % (d,i))
        if os.path.exists(f):
            os.remove(f)

def testCreate(path):
    s = os.path.join(path, r'src.txt')
    open(s, 'w').close()

    for i in range(10):
        print ('create %d' % (i))

        f = os.path.join(path, r'%s\%03d.txt' % (path,i))

        CreateHardLink(s, f)

        count = 0
        while not os.path.exists(f):
            print ('file not found %d %d' % (i, count))
            time.sleep(0.1)
            count += 1

testCreate(sys.argv[1])
C:\temp>python linkPerformanceTest.py \\Nas01\PJ\tmp
create 0
file not found 0 0
file not found 0 1
file not found 0 2
file not found 0 3
file not found 0 4
file not found 0 5
file not found 0 6

(以下略)

これで不思議なのは、Explorer ではきちんとファイルがあると認識されていることなんですね。どうやったら正確な情報を得られるのか。。。謎です。

※。。。と書いている途中で、もしかしたらAPI 経由で取ればいけるのかも?と思えてきました。後から追試してみます。

この症状はネットを漁ってみると Windos に限って起こるわけではなく、NFS ベースの Linux システムでもオプションによっては起こるようです。ただ、各種対応策を取っても解決できなかったのでちょっと特殊な理由なのかもしれません。

こういうの、地味に困るんですよね、、、ある程度時間が経ってから確認するときちんと動くのに、ちょっとシビアなタイミング(テスト環境では4.5秒以内)でアクセスすると発動する地雷なのです。トホホホホ。。。。。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です