2016-06-02 3 views
0

Я работаю над проектом, который должен предоставлять клиентам некоторые представления относительно относительно сложных данных. Есть (по крайней мере) два подхода к этой задачеВеб-Api (mvc, asp.net), задачи подписки и длительные задачи

  1. Чтения данных из БДА, «сбрасывает» его клиент, пусть JS-клиент выполняет все расчеты

  2. стороны сервера (# C) данные нагрузки от БД, вали данные, подходящие для «легкого» JS-клиента (в основном, данные варочной обработки в виде диаграмм D3 или DataTables сразу поймут).

подход (1) полностью действительна, только не уверен, что это действительно соответствует существующей инфраструктуры на лугах в данный момент На данный момент подхода (2) реализуется, и она работает следующим образом .html:

<table id="table1" ...></table> 
<table id="table2" ...></table> 
<table id="table3" ...></table> 
<div id="chartX"/> 
.... 
$(document).ready(function() { 
//initialize a table directly with url to api call: 
    $('#table1').dataTable({ 
     ajax: { 
      url: 'http://app/api/methodZ?param=value', 
      dataSrc: '', 
     }, 
    }); 
// or do a call and initialize table(s) 
    $.ajax({ 
     url: 'http://app/api/methodA?param1=value1&param2=value2', 
     success: function (result) { 
      populatetable2(result.table2Data); 
      populatetable3(result.table3Data); 
     }, 
    }); 

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

  1. API вызовов являются центральным процессором и занимает много времени
  2. Некоторых вызовов параллелизуемы
  3. Там слишком много вызовов, необходимых для заполнения вида клиента из одной страницы
  4. Некоторых вызовов зависят (скажем, есть метод апи Methoda, что является самодостаточным и время/процессор ресурсоемкой, medthodB также время/процессор потребляет и потребности в рамках своей логики для запуска Methoda)

Моя идея была бы следующим образом:

  1. Клиент вызывает только один метод, как «подписаться»
  2. Web API на стороне сервера начинает задание в фоновом режиме и толкает (через SignalR) частичные результаты
  3. клиент получает данные и заполняет интерфейс Поэтапный шаг

.html:

<table id="table1" ...></table> 
<table id="table2" ...></table> 
<table id="table3" ...></table> 
<div id="chartX"/> 
.... 
<script src="~/signalr/hubs"></script> 
.... 
$(document).ready(function() { 
    $.ajax({ 
     url: 'http://app/api/subscribe?paramA=valueA', 
    }); 
}); 

WorkerControllerHub.client.OnDataAReady = function (data) { 
    //fill UI 
} 

WorkerControllerHub.client.OnDataBReady = function (data) { 
    //fill UI 
} 
... 
WorkerControllerHub.client.OnComplete = function (iserror, message) { 
    //nicely notify user if there is an error or all data is loaded 
} 

И на стороне сервера будет вид

WorkerControllerHub { /*SignalR hub*/ } 
WorkerController 
{ 
    private void doAsync(int paramA) 
    { 
     var dataA = calculateA(paramA); 
     WorkerControllerHub.OnDataAReady(dataA); 

     var dataB = calculateB(paramB, dataB); 
     WorkerControllerHub.OnDataAReady(dataA); // 

     WorkerControllerHub.OnComplete(...); 
    } 

    public void Subscribe(int paramA) 
    { 
     sumbitAsyncJob({task/async/... doAsync with paramA}); 
     and immediate return from controller call 
    } 
} 

Я бы сказал, что из моего предыдущего опыта в проектах на стороне сервера C++ или Java, которые я делал с распределенными приложениями, это относительно стандартный подход. (Поскольку довольно некоторый расчетA, calculateB, ... взаимосвязаны, это на самом деле является предпочтительным способом). Однако, читая SO, кажется, что это не тот подход, который нужно предпринять - длительные async-задачи не подходят для IIS + WebAPI + ASP.NET в лучшем виде.

Отсюда мой вопрос - есть ли архитектурные предложения, которые решаются с этой проблемой?

Спасибо.

ответ

1

Определенно, я поеду с расчетами на стороне сервера.

Длинных ходовые функции (работа)
Я думаю, ваши расчетов может быть начат:
- пользователем от клиента, вызовите метод ступицы асинхронной недействительной, начинающуюся работу
- по графику используя что-то вроде FluentScheduler. Вы можете настроить расписание для работы


SignalR Broadcasting
Ваши клиенты могут присоединиться к различным groups в зависимости от того, какие компоненты, которые нуждаются в обновлении, что страница.
Вы можете реализовать что-то вроде класса Broadcaster (который будет вызываться после выполнения задания) и отправить данные пользователям.

public class Broadcaster 
{ 
    private static void BroadcastToGroup(Data data, string groupName) 
    { 
     var clients = GlobalHost.ConnectionManager.GetHubContext<MyHub>().Clients; 
     clients.Group(groupName).UpdateData(data); 
    } 

    private static void BroadcastToAll(Data data) 
    { 
     var clients = GlobalHost.ConnectionManager.GetHubContext<MyHub>().Clients; 
     clients.All.UpdateData(data); 
    } 
} 

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


Recycling
Если вы говорите, ваши расчеты займут некоторое время, вы можете иметь проблемы с IIS Process Recycling. В принципе, каждые 29 часов (по умолчанию) IIS пытается остановить все проблемные потоки и может считать вашу работу одной.
Прочтите это great article о том, как исправить это.

1

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

Смежные вопросы