LoginSignup
1
1

More than 5 years have passed since last update.

Google App Engine SDK 1.9.46 のWindows x64版は罠

Posted at

経緯

解凍して、配置して、goapp serveしたらFailed.

Download the App Engine SDK for Go  |  App Engine standard environment for Go  |  Google Cloud Platform

パッチ

エラーをみると、set_skip_files_re関数が無いヨ。といわれている。たしかにWin32FileWatcherクラスだけ実装されていなかった。以下は付け焼き刃的パッチなので、不完全だとおもいます。app.yaml でskip_files パラメータを使用している環境の方はアップデートを待つほうがいいとおもいます。

app.yaml Reference  |  App Engine standard environment for Python  |  Google Cloud Platform

Version: 1.9.46 - 2016-11-03 Size: 67.7 MB

go_appengine\google\appengine\tools\devappserver2\win32_file_watcher.py
class Win32FileWatcher(object):
  """Monitors a directory tree for changes using win32 API."""
  SUPPORTS_MULTIPLE_DIRECTORIES = False

  def __init__(self, directory):
    """Initializer for Win32FileWatcher.

    Args:
      directory: A string representing the path to a directory that should
          be monitored for changes i.e. files and directories added, renamed,
          deleted or changed.
    """
    self._directory = os.path.abspath(directory)
    self._directory_handle = None
    self._change_set = set()
    self._lock = threading.Lock()  # protects self._change_set
    self._stop = threading.Event()
    self._change_event = threading.Event()
    self._thread = None
+   self._skip_files_re = None

+ def set_skip_files_re(self, skip_files_re):
+   """Allows the file watcher to respect skip_files in app.yaml.
+
+   Args:
+     skip_files_re: The skip_files field of current ModuleConfiguration,
+         defined in app.yaml.
+   """
+   self._skip_files_re = skip_files_re

  def start(self):
    """Start watching the directory for changes."""
    self._directory_handle = ctypes.windll.kernel32.CreateFileW(
        ctypes.c_wchar_p(self._directory),
        ctypes.c_ulong(_FILE_LIST_DIRECTORY),
        ctypes.c_ulong(_FILE_SHARE_READ |
                       _FILE_SHARE_WRITE),
        None,
        ctypes.c_ulong(_OPEN_EXISTING),
        # required to monitor changes.
        ctypes.c_ulong(_FILE_FLAG_BACKUP_SEMANTICS),
        None)
    if self._directory_handle == _INVALID_HANDLE_VALUE:
      raise ctypes.WinError()
    self._thread = threading.Thread(
        target=self._monitor, name='Win32 File Watcher')
    self._thread.start()

  def quit(self):
    """Stop watching the directory for changes."""
    self._stop.set()
    # Note: this will unlock the blocking ReadDirectoryChangesW call.
    ctypes.windll.kernel32.CancelIoEx(self._directory_handle, None)
    self._thread.join()
    ctypes.windll.kernel32.CloseHandle(self._directory_handle)

  def changes(self, timeout_ms=0):
    """Returns the paths changed in the watched directory since the last call.

    start() must be called before this method.

    Args:
      timeout_ms: the maximum number of milliseconds you allow this function to
                  wait for a filesystem change.

    Returns:
      Returns an iterable of changed directories/files.
    """
    if timeout_ms != 0:
      self._change_event.wait(timeout_ms / 1000.0)

    with self._lock:
      result = self._change_set
      self._change_set = set()
      self._change_event.clear()

    return result

  def _monitor(self):
    buff = ctypes.create_string_buffer(_BUFF_SIZE)
    while not self._stop.isSet():
      size_returned = ctypes.c_ulong(0)
      result = ctypes.windll.kernel32.ReadDirectoryChangesW(
          self._directory_handle,
          buff,
          ctypes.c_ulong(_BUFF_SIZE),
          True,  # recursive.
          ctypes.c_ulong(_FILE_NOTIFY_CHANGE_ANY),
          ctypes.byref(size_returned),
          None,
          None)  # this is a blocking call.
      if result == 0 and ctypes.GetLastError() == _ERROR_NOTIFY_ENUM_DIR:
        logging.warning('Buffer overflow while monitoring for file changes.')
        # we need to notify that something changed anyway
        with self._lock:
          self._change_set |= {'Unknown file'}
      if result != 0 and size_returned.value != 0:
        additional_changes = _parse_buffer(buff)
        with self._lock:
          self._change_set |= additional_changes
          self._change_event.set()

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1