У меня три проекта, на российский и зарубежный рынки. Но заказчик-работодатель в России. При этом меня активно тянут в еще один проект, но я по времени просто не укладываюсь.
Более чем. Я семь лет разрабатываю на руби и рельсах, работы больше, чем могу себе позволить по времени. Сейчас вот ищем второго разработчика, найти не можем, все заняты, одни студии остаются.
Вспоминаю «Шагающую смерть» Уильяма Кейта. Там были такое вооружение, как например экранирующие облака, поглощающие лазерное излучение, или боеголовки, набитые вольфрамовыми шариками, выстреливаемыми в одном направлении.
Это не эквивалентное решение. Это решение тех же задач. Да и вообще, я не собираюсь меряться кодом. Человек спросил, как на Elixir сделать аналогичную штуку, я ответил. В общих чертах, но по документации легко будет разобраться в тонкостях.
1. Сколько запустите, столько и будет. Ноды назначаются явно. Разумеется, в случае реального боевого проекта это можно легко автоматизировать.
Однако если я захочу ограничить количество параллельных процессов, я не буду писать велосипед, а использую poolboy.
Да и вообще, poolboy прекрасно решает большинство проблем по распределению задач между процессами.
2. Креш Task уронит вызывающую функцию. Строго говоря, несмотря на парадигму let it crash, я не считаю это хорошей идеей. Но механизм есть.
3. await(task, timeout \\ 5000)
Но опять же, я не считаю остановку в случае вылета по таймауту хорошей идеей. У меня на проекте есть такой вариант:
ret = case Task.yield(task, 60000) do
{:ok, result} ->
result
nil ->
Task.shutdown(task)
:timeout
end
По крайней мере я хочу получить результаты, которые есть. С проблемами разберемся позже. Но у меня такой род приложений, что частичная потеря данных простительна, а вот лишние задержки — не очень хорошо.
4. Нет, тестов нет. При случае сделаю, пока задачи запускать таски на удаленных нодах не было. pmap используем, но на локальных нодах.
У нас проекты на Elixir, и я не вижу смысла писать на Erlang и потом интегрировать код с Elixir, если могу сразу все сделать на Elixir. Даже учитывая то, что мне все равно часто приходится возиться с кодом на Erlang.
Там все значительно проще. Мне кажется, даже статья не понадобится. Смотрите.
Это parallel map на локальной ноде
defmodule Parallel do
def pmap(collection, func) do
collection
|> Enum.map(&(Task.async(fn -> func.(&1) end)))
|> Enum.map(&Task.await/1)
end
end
Чтобы пускать таски на удаленных нодах, нам нужен TaskSupervisor вместо обычного Task
# On the remote node
Task.Supervisor.start_link(name: MyApp.DistSupervisor)
# On the client
Task.Supervisor.async({MyApp.DistSupervisor, :remote@local},
MyMod, :my_fun, [arg1, arg2, arg3])
Естественно, супервизор надо будет в supervision tree добавить или пускать через start_link, и модуль на нодах написать, который будет дергаться через TaskSupervisor. Остальное сделает эликсир сам.
Часто ли в CS играют в симметричные игровые режимы? Обычно это TDM и бомба, то есть такие режимы, в которых симметрия карты не имеет значения.
Я же говорю о симметричных режимах, когда у обоих команд одна цель, и победа зависит еще от того, насколько сбалансирован доступ к цели. Если одна команда в силу дизайна карты легче захватывает цель, чем другая — это не ок.
Ну в играх типа захвата флага карты должны быть симметричными, иначе одна из команд получает серьезное преимущество. Есть одна карта в Дестини 2, где на режиме захвата точек исход боя чаще решает не уровень команды, а сторона старта — если старт с точки С, это почти всегда проигрыш, потому что практически невозможно отбить B и крайне сложно взять хотя бы A. Единственный шанс — перевернуть стороны, всеми силами навалившись на A, потом продавить B и оставить врагам C. Но такое возможно только при полной командной игре, не с рандомными игроками.
Другое дело, что можно делать карты симметричными, но с разным оформлением сторон, чтобы карта не выглядела едино. Скажем, пустыня с разбросанными укрытиями и крепость. Если сверху посмотреть на такую карту, она будет выглядеть симметрично, но при игре изнутри будет смена обстановки при переходе между сторонами. Это я все с позиций FPS говорю, конечно.
В Erlang вообще нет глобальных и статических переменных, только локальные, принадлежащие стеку или куче процесса. Процесс закончился — память очищаем, все в мусорку улетело, все параметры, переменные, результаты, мэйлбокс. Хотите что-то передать — будьте добры явно этим озаботиться. Собственно, для того gen_server и придумали, чтобы можно было эмулировать сохранение состояния.
Есть правда нюанс с бинарниками, самый известный способ все-таки выстрелить себе в ногу, когда большие бинарники лежат в куче и на них передаются ссылки другим процессам. Я так словил знатную утечку памяти один раз, когда еще не знал особенностей. Но если об этом знать и знать решения, то это дело можно купировать.
Для меня слак кроме коммуникатора еще и удобный интерфейс для автоматизации. Вечерние тесты в отдельном канале (специфика такая, что надо каждый вечер смотреть, как за день отработали сервисы, в срезе проблему не увидеть). Экспресс-тест одной командой, информация сразу в чат. Ворнинги от заббикса тоже в отдельном канале.
Для менеджеров пачка команд, формирующих отчеты сразу в чат, текстом и файлом. Гораздо удобнее, чем лезть в админку, искать нужный отчет, и так далее.
Правда у нас команда маленькая, флуда нет, проблем описанных нет. Может поэтому мне слак по душе.
Извините, но Cities Skylines отлично работала у меня на GTX660, и отлично работает на 1050Ti. Единственное, что этой игре реально требуется, так это память. Когда поставил 16 вместо 8, игра стала гораздо быстрее грузиться, стабильнее работать и перестала вылетать в принципе. Правда у меня модов и моделей на несколько гигабайт. Когда играл в ванильную версию, хватало и восьми гигабайт.
1. Сколько запустите, столько и будет. Ноды назначаются явно. Разумеется, в случае реального боевого проекта это можно легко автоматизировать.
Однако если я захочу ограничить количество параллельных процессов, я не буду писать велосипед, а использую poolboy.
Да и вообще, poolboy прекрасно решает большинство проблем по распределению задач между процессами.
2. Креш Task уронит вызывающую функцию. Строго говоря, несмотря на парадигму let it crash, я не считаю это хорошей идеей. Но механизм есть.
3. await(task, timeout \\ 5000)
Но опять же, я не считаю остановку в случае вылета по таймауту хорошей идеей. У меня на проекте есть такой вариант:
По крайней мере я хочу получить результаты, которые есть. С проблемами разберемся позже. Но у меня такой род приложений, что частичная потеря данных простительна, а вот лишние задержки — не очень хорошо.
4. Нет, тестов нет. При случае сделаю, пока задачи запускать таски на удаленных нодах не было. pmap используем, но на локальных нодах.
У нас проекты на Elixir, и я не вижу смысла писать на Erlang и потом интегрировать код с Elixir, если могу сразу все сделать на Elixir. Даже учитывая то, что мне все равно часто приходится возиться с кодом на Erlang.
Это parallel map на локальной ноде
Чтобы пускать таски на удаленных нодах, нам нужен TaskSupervisor вместо обычного Task
Естественно, супервизор надо будет в supervision tree добавить или пускать через start_link, и модуль на нодах написать, который будет дергаться через TaskSupervisor. Остальное сделает эликсир сам.
Ссылки, куда посмотреть можно:
hexdocs.pm/elixir/Task.Supervisor.html
elixir-recipes.github.io/concurrency/parallel-map
elixir-lang.org/getting-started/mix-otp/distributed-tasks-and-configuration.html
Я же говорю о симметричных режимах, когда у обоих команд одна цель, и победа зависит еще от того, насколько сбалансирован доступ к цели. Если одна команда в силу дизайна карты легче захватывает цель, чем другая — это не ок.
Другое дело, что можно делать карты симметричными, но с разным оформлением сторон, чтобы карта не выглядела едино. Скажем, пустыня с разбросанными укрытиями и крепость. Если сверху посмотреть на такую карту, она будет выглядеть симметрично, но при игре изнутри будет смена обстановки при переходе между сторонами. Это я все с позиций FPS говорю, конечно.
В Erlang вообще нет глобальных и статических переменных, только локальные, принадлежащие стеку или куче процесса. Процесс закончился — память очищаем, все в мусорку улетело, все параметры, переменные, результаты, мэйлбокс. Хотите что-то передать — будьте добры явно этим озаботиться. Собственно, для того gen_server и придумали, чтобы можно было эмулировать сохранение состояния.
Есть правда нюанс с бинарниками, самый известный способ все-таки выстрелить себе в ногу, когда большие бинарники лежат в куче и на них передаются ссылки другим процессам. Я так словил знатную утечку памяти один раз, когда еще не знал особенностей. Но если об этом знать и знать решения, то это дело можно купировать.
Для менеджеров пачка команд, формирующих отчеты сразу в чат, текстом и файлом. Гораздо удобнее, чем лезть в админку, искать нужный отчет, и так далее.
Правда у нас команда маленькая, флуда нет, проблем описанных нет. Может поэтому мне слак по душе.