2015-07-28 2 views
0

У меня есть конечная точка REST, и ей нужно обработать длинный список кодов. Поскольку это может вызвать тайм-ауты, я стараюсь использовать функцию spawn и делать магию в фоновом режиме. Но похоже, что функция spawn удерживает ответ 200 OK от моей конечной точки REST, поэтому она не является нерестом.MarkLogic 7 spawn-function

Я добавил строки журнала, чтобы проверить, где они находятся. Все журналы отображаются в журнале отладки.

С небольшим количеством данных это отлично работает. С большим набором (коды 60k) он терпит неудачу.

После изменения кода на нерест функцию для каждого элемента $ текста, поэтому 60K нерестится, я получаю эту ошибку:

2015-07-28 10:20:02.326 Debug: Forest::insert: STRLF3-content-001-1 XDMP-INMMFULL: In-memory storage full; list: table=5%, wordsused=3%, wordsfree=95%, overhead=1%; tree: table=8%, wordsused=3%, wordsfree=97%, overhead=0% 

вставленные данные:

{ 
    ProjectID: 102124, 
    Text: "2311\n2253\n2312\n6626\n2253\n1234" 
} 

Назвав икры:

(: ======================================================================= :) 
(: ! Load Transactions into seperate XML files        :) 
(: ======================================================================= :) 

declare 
%roxy:params("") 
function strlf:post(
    $context as map:map, 
    $params as map:map, 
    $input as document-node()* 
) as document-node()? 
{ 
    map:put($context, "output-types", "application/json"), 
    xdmp:set-response-code(200, "OK"), 
    document { 

        (: Get project ID :) 
        let $_ := xdmp:log('TransTest - stap1', 'debug') 
        let $project := json:transform-from-json($input)/ns:ProjectID 

        let $_ := xdmp:log('TransTest - stap2', 'debug') 
        let $codes := json:transform-from-json($input)/ns:Text 

        (: Clean current project :) 
        let $_ := xdmp:log('TransTest - stap3', 'debug') 
        let $uridir := fn:concat('/app/transactie/', $project/text(), '/', '*') 

        let $_ := xdmp:log('TransTest - stap4', 'debug') 
        let $kill  := xdmp:document-delete(cts:uri-match($uridir)) 

        (: Spawn the trannies :) 
        let $_ := xdmp:log('TransTest - stap5', 'debug') 

        (: return 'ja' :) 
        let $_ := xdmp:spawn-function(strlf:spawner($project, $codes, $uridir), 
        <options xmlns="xdmp:eval"> 
         <transaction-mode>update-auto-commit</transaction-mode> 
        </options>) 

        return 'done' 

    } 
}; 

Функция strlf: порождения:

declare private function strlf:spawner(
    $project, 
    $codes, 
    $uridir 
) 
{ 
    (: Tokenize on lines :) 
    let $text  := fn:tokenize($codes, fn:codepoints-to-string(10)) 

    let $loop  := 
    for $regel in $text 

     let $tokregel := fn:tokenize($regel, ",")   

     let $intvalue := 
     if (fn:contains($regel, ",")) 
     then fn:substring-after($regel, "€") 
     else 1 

     let $code := 
     if (fn:contains($regel, ",")) 
     then $tokregel[1] 
     else $regel 

     (: Build map of maps, p4 should be postcode :) 
     let $map  := map:map() 
     let $_  := map:put($map, 'code', $code) 
     let $_  := map:put($map, 'p4', fn:substring($code[1], 1, 4)) 
     let $_  := map:put($map, 'value', $intvalue) 
     let $_  := map:put($map, 'projectid', $project/text()) 

     (: Create unverified random doc id :) 
     let $docid := fn:string(xdmp:random(1000000000000)) 

     (: Build URI :) 
     let $uridoc := fn:concat('/app/transactie/', $project/text(), '/', $docid, '.xml') 

    (: Save transaction document and skip header :) 
    return 
    (if (map:get($map, 'code') != 'CODE') 
    then xdmp:document-insert 
      (
      $uridoc, 
       <transaction xmlns='http://www.dikw.nl/transactions' projectid='{map:get($map, 'projectid')}' code='{map:get($map, 'code')}' p4='{map:get($map, 'p4')}'> 
       <value>{map:get($map, 'value')}</value> 
       </transaction> 
      ) 
    else()) 

    (: Empty return :) 
    return $loop   
}; 

ответ

1

Правильно, у вас есть strlf:spawner($project, $codes, $uridir) в качестве первого аргумента xdmp:spawn-function, заставляя его получить выполняется, и результат передается в xdmp:spawn-function. И так как функция spawner возвращает пустую последовательность, никакая ошибка не генерируется функцией spawn.

Исправление довольно просто, обернуть Spawner вызов в анонимной функции:

let $_ := xdmp:spawn-function(function() { strlf:spawner($project, $codes, $uridir) }, 
       <options xmlns="xdmp:eval"> 
        <transaction-mode>update-auto-commit</transaction-mode> 
       </options>) 

HTH!

+0

Спасибо. Это похоже на то, что я хотел. Но теперь каждый вариант режима транзакции отклоняется. Кажется, я не могу обновить/вставить этот путь. – Thijs

+0

Я добавил параметр «update» и фиксацию в нижней части порожденной функции. Кажется, сейчас хорошо работать! – Thijs

+1

Похоже, что вы используете MarkLogic 7. «update-auto-commit» поддерживается как MarkLogic 8. Добавление «xdmp: commit()» и использование режима «update» - действительно правильный способ заставить его работать в MarkLogic 7. – grtjn