Какие средства С# существуют для запуска, очереди, определения приоритетов зависимых задач

У меня есть приложение службы С#, которое взаимодействует с базой данных. Он был недавно перенесен с .NET 2.0 на .NET 4.0, поэтому есть много новых инструментов, которые мы могли бы использовать.

Я ищу указатели на подходы к программированию или инструменты/библиотеки для обработки заданий, настройки задач, от которых они зависят, очереди, приоритизации, отмены и т.д.

Существуют различные виды услуг:

  • Данные (для извлечения и обновления)
  • Вычисление (заполнение некоторой таблицы результатами расчета данных)
  • Отчеты

Эти службы часто зависят друг от друга и запускаются по требованию, т.е. задача Отчетность, вероятно, будет содержать в себе код, например

if (IsSomeDependentCalculationRequired())
    PerformDependentCalculation();  // which may trigger further calculations
GenerateRequestedReport();

Кроме того, любая модификация Данные скорее всего установит флаг Required для некоторых служб Расчет или Отчеты (так что отчет может быть устаревшим до его завершения). Задачи варьируются от нескольких секунд до нескольких минут и выполняются в транзакциях.

До сих пор это работало нормально, но оно недостаточно масштабируется. Есть фундаментальные проблемы с дизайном, и я хочу переписать эту часть кода. Например, если два пользователя запросят один и тот же отчет в одинаковые моменты времени, зависимые задачи будут выполняться дважды. Кроме того, в настоящее время нет способа отменить выполняемую задачу. Трудно поддерживать зависимые задачи и т.д.

Я НЕ ищу предложения о том, как реализовать исправление. Скорее, я ищу указатели на то, какие инструменты/библиотеки я буду использовать для такого требования, если я начинаю с .NET 4 с нуля. Будет ли это хорошим кандидатом для Рабочий процесс Windows? Это то, что для Фьючерсы? Есть ли какие-нибудь другие библиотеки, на которые я должен смотреть, или книги или записи в блогах, которые я должен прочитать?

Изменить: Как насчет Rx Reactive Extensions?

Ответ 1

Я не думаю, что ваши требования вписываются в любой встроенный материал. Ваши требования слишком специфичны для этого.

Я бы рекомендовал вам создать инфраструктуру очереди задач вокруг базы данных SQL. Ваши задачи довольно длительные (в секундах), поэтому вам не нужна высокая пропускная способность в планировщике задач. Это означает, что вы не столкнетесь с препятствиями производительности. Это будет довольно управляемая задача с точки зрения программирования.

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

Мое главное состоит в том, что ваши требования таковы, что вам нужно использовать код С# для их кодирования. Вы не можете сделать существующий инструмент подходящим для ваших нужд. Чтобы сделать это самостоятельно, вам необходима полная формулировка языка программирования.

Изменить: вам, вероятно, следует отделить запрос задачи от выполнения задачи. Это позволяет нескольким сторонам запрашивать обновление некоторых отчетов, в то время как выполняется только одно фактическое вычисление. Как только это единственное вычисление завершено, все запросы задачи отмечены как завершенные. Когда запрос отменяется, исполнение не нужно отменять. Только после отмены последнего запроса выполнение задачи также отменяется.

Изменить 2: Я не думаю, что рабочие процессы - это решение. Рабочие процессы обычно работают отдельно друг от друга. Но ты этого не хочешь. Вы хотите иметь правила, которые охватывают несколько задач/рабочих процессов. Вы будете работать против системы с моделью на основе рабочего процесса.

Редактировать 3: Несколько слов о TPL (параллельная библиотека задач). Вы упомянули об этом ( "Фьючерсы" ). Если вам нужно вдохновение в том, как задачи могут работать вместе, как могут быть созданы зависимости и как могут быть созданы задачи, посмотрите на параллельную библиотеку задач (в частности, на классы Task и TaskFactory). Там вы найдете красивые шаблоны дизайна, потому что они очень хорошо разработаны. Вот как вы моделируете последовательность задач: вы вызываете Task.ContinueWith, который будет регистрировать функцию продолжения как новую задачу. Вот как вы моделируете зависимости: TaskFactory.WhenAll(Task []) запускает задачу, которая запускается только после завершения всех задач ввода.

НО: сам TPL, вероятно, не очень подходит для вас, потому что его задача не может быть сохранена на диске. Когда вы перезагружаете свой сервер или развертываете новый код, все существующие задачи отменяются и процесс прерывается. Это, вероятно, будет неприемлемым. Пожалуйста, просто используйте TPL как вдохновение. Узнайте от него, что такое "задача/будущее" и как они могут быть составлены. Затем выполните свою собственную задачу.

Помогает ли это?

Ответ 2

Я попытался бы использовать пакет конечного автомата stateless для моделирования рабочего процесса. Использование пакета обеспечит последовательный способ продвижения состояния рабочего процесса через различные службы. Каждая из ваших служб будет иметь внутреннюю реализацию statemachine и выставить методы для ее продвижения. Безстоящее будет доступно для запуска действий, основанных на состоянии рабочего процесса, и принудит вас к явным настройкам различных состояний, в которых он может быть, - это будет особенно полезно для обслуживания, и это, вероятно, поможет вам лучше понять домен.

Ответ 3

Если вы хотите решить эту фундаментальную проблему правильно и масштабируемо, вы, вероятно, должны выглядеть как стиль архитектуры SOA. Ваши службы получат команды и генерируют события, которые вы можете обработать, чтобы реагировать на факты, происходящие в вашей системе.

И да, есть инструменты для этого. Например, NServiceBus - замечательный инструмент для создания SOA-систем.

Ответ 4

Вы можете сделать агент данных SQL для выполнения SQL-запросов в заданном интервале. Вы должны написать приложение самостоятельно, это похоже. Напишите как длинную программу, которая проверяет время и что-то делает. Я не думаю, что есть четкие инструменты, чтобы делать то, что вы пытаетесь сделать. Сделайте приложение С#, службу WCF. автоматизация данных может быть выполнена в самом sql.

Ответ 5

Если вы правильно поняли, что хотите кэшировать созданные отчеты и не работать снова. Как отмечали другие комментаторы, это можно легко решить с помощью нескольких очередей Producer/Consumer и некоторых кешей. Сначала вы ставите в очередь свой запрос на отчет. На основе параметров генома отчета вы можете сначала проверить кеш, если уже сформированный отчет уже доступен, и просто верните его. Если из-за изменений в базе данных отчет становится устаревшим, вам необходимо позаботиться о том, чтобы кэш был недействительным надежным образом.

Теперь, если отчет еще не был создан, вам нужно запланировать отчет для генерации. Планировщик отчетов должен проверить, не создан ли тот же отчет. Если да, зарегистрируйте событие, чтобы уведомить вас, когда оно будет завершено, и верните отчет после его завершения. Убедитесь, что вы не получаете доступ к данным через слой кеширования, поскольку он может создавать расы (создается отчет, данные изменяются, и готовый отчет немедленно отбрасывается кэшем, оставляя уведомление о возврате).

Или, если вы хотите предотвратить возврат устаревших отчетов, вы можете позволить кешированию стать вашим основным поставщиком данных, который будет генерировать столько отчетов, пока не будет сформирован один отчет во времени, который не был устаревшим. Но имейте в виду, что если у вас есть постоянные изменения в вашей базе данных, вы можете войти в бесконечный цикл здесь, постоянно создавая недопустимые отчеты, если время генерации отчета больше, чем среднее время между изменениями вашего дБ.

Как вы можете видеть, у вас здесь много вариантов, не говоря уже о .NET, TPL, SQL-сервере. Сначала вам нужно установить свои цели, насколько быстро/масштабируемо и надежно ваша система должна быть тогда вам нужно выбрать соответствующий архитектурный проект, как описано выше для вашего конкретного проблемного домена. Я не могу сделать это за вас, потому что у меня нет полного домена, знаю, что приемлемо, а что нет.

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

TPL и SQL-сервер могут помочь там точно, но это только инструменты. Если неправильно использовать из-за недостаточного опыта с тем или иным, может оказаться, что другой подход (например, использование только в очередях памяти и сохраненных отчетов в файловой системе) лучше подходит для вашей проблемы.

Из моего нынешнего понимания я бы не использовал SQL-сервер, чтобы использовать его как кеш, но если вы хотите использовать базу данных, я бы использовал нечто вроде RavenDB или RaportDB, которые выглядят стабильными и намного более легкими по сравнению с полномасштабным SQL-сервером.

Но если у вас уже запущен SQL-сервер, то используйте его.

Ответ 6

Я не уверен, правильно ли я вас понял, но вы можете взглянуть на планировщик JAMS: http://www.jamsscheduler.com/. Это несвободная, но очень хорошая система планирования задач и отчетов. Я использовал его с успехом в своей предыдущей компании. Он написан на .NET, и для него есть .NET API, поэтому вы можете писать свои собственные приложения, обменивающиеся данными с JAMS. Они также имеют очень хорошую поддержку и стремятся реализовать новые функции.