03.18 Git и оформление патчей в виде файлов
Как работать совместно, если доступна только [голубиная почта, магнитные ленты, телеграф, иное]?
- git push/pull недоступны
- пересылать можно только файлы
⇒ Пересылать проделанную работу.
Классический: patch + diff
использование diff для изготовления патча и patch для наложения.
Формат патча, изготовленного diff -u (unified diff)
Изговтовить список процессов ps -ef > файл1. Позапускать левые программы. Изговтовить список процессов ps -ef > файл2. Получить unified diff этих файлов, записать его в файл.patch. Применить патч.
- Git и unified diff/path
Использование git format-patch и git am
Создать репозиторий. Четырежды выполнить последовательность команд
С помощью git format-patch сделать патчсет на последние три коммита
Сделать ветку на базе первого коммита
- Применить патчсет к этой ветке
- Посмотреть результаты
- Сетевое взаимодействие
async'овский echo-сервер из лекции, что и как работает
- FIXME: сокет после закрытия программы иногда не освобождается ("подвисает" на ~полторы минуты), надо подключаться с опцией "socket.SO_REUSEADDR" (выяснить, как это делать в Питоне)
модифицировать echo-сервер таким образом, чтобы он воспринимал строки вида команда параметры:
print произвольные слова — вывод произвольных слов
info {host|port} — вывод адреса или порта клиента (writer.get_extra_info('peername'))
send/receive-клиент из лекции
Модифицировать send/receive-клиент, добавив туда cmd из двух команд выше, причём в команде info должно поддерживаться достраивание параметров (host и port)
- (FIXME: не влезло по времени, даже при выпавшей демке про patch; модификация echo-сервера заняла много времени)
Как сделать пролистывание подстановок в дополнение к показу списка? Это свойство GNU Readline, конкретно — функция menu-complete (). Задаётся помещением строки "последовательность": menu-complete в файл ~/.inputrc. Например, Shift+Tab:
"\e[Z": menu-complete
Д/З
Задача_1. MUD в формате клиент-сервер (однопользовательский), оформление изменений в виде патчсета.
Скопируйте решение Задачи_1 с предыдущего занятия. Сделайте коммит. Далее этот коммит будет обозначаться
Продолжите историю на ветке work
- Переведите монолитную реализацию MUD на схему "клиент+сервер" (однопользовательскую)
- клиент отвечает за:
- получение команд от пользователя, их разбор, проверку корректности (включая вывод сообщений о некорректных командах)
- вывод информации, полученной от сервера
- т.е. по сути клиент не имеет состояния
сервер работает по принципу echo-сервера, воспринимающего строки вида команда параметры
- сервер отвечает за хранение и модификацию состояния игры, включая:
- позицию игрока
- расположение монстров, их типы и количество очков здоровья (о.з.)
организация протокола клиент->сервер:
по протоколу передаются только команды с гарантированно корректными параметрами; сервер не занимается их перепроверкой (в жизни - не так )
- набор команд протокола следует сделать более простым, чем набор пользовательских команд:
- не нужны опциональные параметры; если пользователь опустил опциональный параметр, клиентом в команду для сервера подставляется значение по умолчанию
- можно все параметры сделать позиционными
однотипные команды можно объединять в одну, с различением по параметрам: например, единственная команда перемещения с указанием приращения по каждой координате (вместо up: move 0 -1, вместо right: move 1 0)
- в целом, клиент выполняет "частичное переваривание" пользовательского ввода и передает серверу упрощенный и гарантированно корректный результат
организация протокола сервер->клиент:
- сервер возвращает только те данные, которые нужны клиенту для вывода
- сервер отвечает на каждую команду клиента без каких-либо задержек
- клиент вправе ждать ответа сервера на отправленную команду, и возвращаться к приёму пользовательских команд только после получения ответа
- по сути, параллелизма в работе клиента и сервера НЕТ
- важные частные случаи:
"энкаунтер" (т.е. перемещение игрока в позицию с монстром): на сервер поступает команда перемещения, в ответ сервер шлёт имя монстра и его приветственный текст; рендерингом с помощью cowsay занимается клиент
- атака: на сервер шлётся имя монстра и количество о.з., соответствующее выбранному оружию; сервер отвечает - либо что монстра с таким именем в позиции нет; либо (если монстр есть), то количеством списанных о.з. и количеством оставшихся о.з. (если второе равно 0, значит монстр убит)
- ДИСКЛЕЙМЕР: вышесказанное - не готовый проект протокола, а намёки на то, как его имеет смысл построить!
- клиент отвечает за:
оформите реализацию в виде набора коммитов на ветке work, желательно не менее 3 коммитов
- сформируйте по этому набору коммитов патчсет:
создайте подкаталог patchdir
при помощи команды git format-patch с ключом --output-directory создайте в подкаталоге patchdir патчсет, включающий все коммиты, реализующие клиент-серверную схему
- закоммитьте файлы патчсета
- примените патчсет:
скопируйте каталог patchdir в место, находящееся вне git-репозитория (далее путь к этому месту обозначен как path_to_patchdir)
создайте ветку apply_patch от коммита , переключитесь на неё (проверьте!)
при помощи команды git am path_to_patchdir/patchdir/* примените патчсет
проверка: посмотрите структуру веток при помощи gitk; на ветках work и apply_patch должны быть одинаковые наборы коммитов