Napi api: Batch API

Kategória: 
Leírás
Napi api: Batch API

Well, talán harmadjára futok össze a batch apival, és még mindig nem volt zökkenőmentes a barátság, szóval amíg az a betyár sok elem leszalad, amin dolgoztam, levésem gyorsan a tudnivalókat, hogy legközelebb már ne kelljen megint mindenre rájönni.

No akkor batch api:

A batch kötegelt feldolgozást jelent. Drupalon belül úgy is mondhatjuk, hogyha egyszerre annyi adattal kell dolgozni, ami túlnő egy oldalletöltés korlátjain, akkor kell a batch apihoz nyúlni. A képet megnézve valószínű egyébként, hogy egyből leesik, a Drupal melyik részéről is van szó.

Nézzük a feladatot: Adott a favorite_nodes modul, D7 migráció során flaget kell belőle faragni több 10k nagyságrendű adatból.

A batch api maga két fő részből áll. Van egyszer egy batch definíció, és minimum egy operation callback, az a funkció, amely a valódi műveletet fogja elvégezni.

Így néz ki nagyjából egy batch definíció:

  $batch = array(
    'operations' => array(
      array('operation_callback', array())
    ),
    'finished' => 'favorite_nodes_to_flag_batch_finished',
    'title' => t('Convert all favorite nodes to flag'),
    'init_message' => t('Convert starting..'),
    'progress_message' => t('Processed @current out of @total.'),
    'error_message' => t('Hmm.. Something could be wrong, sorry, post an issue to module..'),
  );

Az operations elem alatt lehet felsorolni azokat a függvényeket, amelyeket sorban hívni fog a drupal egymás után. Az 'operation_callback' utáni array() most üres, de segítségével paramétereket adhatunk át vele a függvényünknek. Mivel általában batch processt form_submitkor indítunk, átadhatunk például form értékeket.

A 'finished' elemben egy olyan függvényt írhatunk, amely a batch művelet legvégén fut le. Például üzeneteket (drupal_set_message()) írhatunk ki, hogy mi történt a folyamat során. Figyi, ez nem array, ebből csak egy van!

Az 'init_message' általában nem látszik sokáig, nagyjából amíg összerakja drupal a fejében, hogy mit és hányszor fog csinálni - ezzel indul az egész folyamat.

Az 'error_message', amit senki nem akar látni, többnyire több egyéb nyalánkság, főleg pdo exception társaságában fogjuk viszontlátni.

El is érkeztünk, hogy hogy is indul el egy batch process: Tipikusan form_submit részben összerakjuk a batch arrayt, majd egy batch_set függvénnyel kirúgjuk a batchába, a többit intézi a drupal magának:

function my_module_form_submit($form, &$form_state) {
  $batch = array(lásd felül);
  batch_set($batch);
}

Ezzel elkezdődik az operation része a batchnek. Ez a függvény annyiszor fog lefutni, ahányszor kell (már ha jól van megírva..)
Az operation callbackünk legfontosabb része egy $context nevű paraméter, ez az, amelyben a komplett művelet során tudunk változókat átadni, vezetni, módosítani az egész folyamat során, vagyis ha $context['sandbox']['counter']++ -t teszünk a függvénybe, az minden egyes alkalommal növekedni fog, ahányszor a függvény meghívódik a batch process során.

Ennek a $context paraméternek a következő részeit állítgathatjuk:

$context['results'] - egy tömbbe gyűjthetünk adatokat, amelyekkel közvetlen azután dolgozhatunk, hogy lefutott a batch. Ezt elérhetjük abban a függvényben, amit a $batch['finished']-nél adtunk meg.

$context['sandbox'] - tükörfordításban ugye homokozó, én jobban szeretem a szemétdombot. Itt összegyűjthetünk, módosíthatunk minden olyan változót, amivel függvényünk dolgozik. Például ahogy fentebb is volt már, hogy hányszor futott a process.

$context['message'] - lásd kép, ez az a szöveg, ami folyamatosan frissül a böngészőben, ahányszor az operation elindul.

$context['finished'] - Hogy hány %-nál jár a művelet. Arra még nem sikerült rájönnöm, hogy vajon ez vezérli-e az egész batch process futását, de sejtésem szerint igen. Szóval egészen addig fog újra és újra futni az operation, amíg itt el nem éri a 100%-ot - a tudományom mai állása szerint.

Nézzünk egy ilyen függvényt, és magyarázzunk:

function MODULOM_batch_operation(&$context) {
  // Az első futásnál ez a $context['sandbox'] üres
  // Ilyenkor kell feltölteni inicializálni pár dolgot
  if (empty($context['sandbox'])) {
    // Ez lesz most a számlálónk, vagyis hogy hány elemet dolgoztunk fel.
    $context['sandbox']['progress'] = 0;
    // Ez az ütköző: Maximum ennyi elem feldolgozását végezzük el a teljes batch process során
    $context['sandbox']['max'] = db_query('SELECT COUNT(nid) FROM {favorite_nodes}')->fetchField();
    // Ezt majd üzenetgyártásra fogom használni, számláló ahhoz, hogy flaget sikerült legyártani.
    $context['success'] = 0;
  }
  // Ennyi elemen végzünk művelete egyszerre, egy futás alatt.
  $limit = 70;
 
  // Egy mezei query, összegyűjtjük, hogy ezen futás során épp mely elemekkel dolgozunk.
  // Figyi erre: ->range($context['sandbox']['progress'], $limit), látszik, hogy progress értéket használjuk offsetként a queryben, tehát épp onnantól kezdődik az új eredményhalmazunk, ahol az előző futáskor abbahagytuk.
  $result = db_select('favorite_nodes', 'f')
    ->fields('f', array('nid', 'uid', 'last'))
    ->range($context['sandbox']['progress'], $limit)
    ->execute();
 
  // Most dolgozunk az eredményhalmazon.
  foreach ($result as $row) {
    // Először növeljük a progresst.
    $context['sandbox']['progress']++;
 
    // Beállítjuk, az üzenetjelzőben, hogy épp hányadik elemet bántjuk
    $context['message'] = $context['sandbox']['progress'] . ' item processed.';
 
    // Ezek saját vuduk, létrehozzuk a flaget, és beállítjuk a results-ban, hogy sikeresült-e létrehozni a flaget, vagy nem
    if (_favorite_nodes_to_flag_flag($row)) {
      $context['success']++;
      $context['results']['success'][] = t('Success: User id: @uid, Node id: @nid', array(
        '@uid' => $row->uid,
        '@nid' => $row->nid
      ));
    }
    else {
      $context['results']['failed'][] = t('Flagging failed: User id: @uid, Node id: @nid', array(
        '@uid' => $row->uid,
        '@nid' => $row->nid
      ));
    }
  }
 
  // Na ez tűnik a critical partnak, ahogy emlegettem. Ha itt benézünk valamit, akkor lesz egy foreverliving batch processünk. Szóval figyeljünk, hogy hogyan állítjuk be az ütközőt.
  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  }
}

Érdemes batch gyártásnál először a keretet elkészíteni, esetleg egy hülyebiztos lekérdezéssel húzni az időd műveletenként, hogy pontosan úgy fut-e, azon az elemeken, amikkel nekünk kell. Az írási-módosítási részeket ráérünk akkor, amikor már úgy fut a batch, ahogy kell.

Ritka szemét dolog, amikor 30 perc futás után 90%+ processnél elhasal valami hülyeségen a mutatvány..

Hozzászólások

Get More Info generic cialis

Get More Info generic cialis liquid - buy cialis 10mg online

buy generic valium online

buy generic valium online long will 10mg valium last - buy valium from roche

buy cialis buy cialis online

buy cialis buy cialis online australia - cialis over the counter

buy cialis generic cialis

buy cialis generic cialis online no prescription - buy generic cialis online australia

website street price valium

website street price valium 10 mg - valium online topix

read this cost valium 2mg -

read this cost valium 2mg - does 10mg valium feel like

buy valium cheap online

buy valium cheap online valium gegen depression - buy valium online legally uk

generic valium pill

generic valium pill identifier valium effects sleep - valium good social anxiety disorder

buy valium from canada what

buy valium from canada what does valium drug do - buy generic valium online no prescription

online pharmacy for valium

online pharmacy for valium valium vs antidepressants - pill identifier valium 10

more information cialis

more information cialis coupon offer - cialis daily study

buy cialis online cialis

buy cialis online cialis online rx reviews - cialis online reviews

Check Out Your URL generic

Check Out Your URL generic cialis 20 mg canada - cialis daily dose effectiveness

More hints cialis online

More hints cialis online canadian pharmacy - cialis good price

us buy cialis online nz -

us buy cialis online nz - cheap cialis with prescription

valium online diazepam valium

valium online diazepam valium ingredients - is generic valium the same

rilsseo プラダ バッグ pjyzobz

rilsseo プラダ バッグ pjyzobz nifyyzb プラダ アウトレット hnahphg vpwicne プラダ バッグ krhmhdv jblzpfe http://www.pradasite2013.com/ njnrrlg scguhxx プラダ バッグ bkaxqkr iociqal プラダ 財布 magyqtg yvcamdk プラダ バッグ umoqndg wlvdati http://www.annkapradashop.com/ hlizjzy kktpmcd プラダ アウトレット bvkycdv dmyeune prada アウトレット ulouvgb jhzccyp prada アウトレット qeksxfo vtojwej http://www.cheappradaja.com/ xkkayhf thxttpc プラダ バッグ flnacri fpisxej プラダ バッグ kknakgh dmwmshz プラダ バッグ hpeevbh zhlheso http://www.pradaonly.com/ gfiwtrs bptalaq プラダ アウトレット xkuifcw pvwchpi Prada アウトレット vvyupzr qphqeaw プラダ アウトレット wugfpmq zljqflg http://www.pradafassyon.com/ uboxlcc

tramadol online is it legal

tramadol online is it legal to buy tramadol online us - buy tramadol online safely

Izeke, valami nem tiszta.

Izeke, valami nem tiszta. Akkor most a finished 1-tol 100-ig no, vagy 0-tol 1-ig vagy hogy? Mert a peldaban nem szazalekot szamolsz (ami ugye progress * 100 / max) hanem csak progress/max, ami a legjobb akarattal is egy 0 es egy kozotti ket vegen zart intervallumba eso szamot ad.

Igazad lészen, 0-1-ig megy az

Igazad lészen, 0-1-ig megy az érték, és a megfelelő % lesz kiírva a futás alatt.

Jó írás ez, köszi! Lazán

Jó írás ez, köszi!
Lazán kapcsolódik hozzá, hogy a hook_update_N() függvénynek is van egy &$sandbox paramétere, pont a Batch API miatt:

„If your update task is potentially time-consuming, you'll need to implement a multipass update to avoid PHP timeouts. Multipass updates use the $sandbox parameter provided by the batch API (normally, $context['sandbox']) to store information between successive calls, and the $sandbox['#finished'] value to provide feedback regarding completion level.”

Hozzászólás

A mező tartalma nem nyilvános.
  • Internal paths in double quotes, written as "internal:node/99", for example, are replaced with the appropriate absolute URL or relative path.
  • Engedélyezett HTML elemek: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <del> <img>
  • A webcímek és email címek automatikusan linkekké alakulnak.
  • A sorokat és bekezdéseket a rendszer automatikusan felismeri.
  • Engedélyezett HTML elemek: <a> <blockquote> <br> <cite> <code> <dd> <del> <div> <dl> <dt> <em> <li> <ol> <p> <span> <strong> <ul>
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <bash>, <c>, <cpp>, <drupal5>, <drupal6>, <java>, <javascript>, <mysql>, <php>, <python>, <ruby>, <sql>. The supported tag styles are: <foo>, [foo].
  • Minden email cím át lesz alakítva ember által olvasható módon, vagy (ha a JavaScript engedélyezett) ki lesz cserélve kattintható, de biztonságos hivatkozásra.
Type the characters you see in this picture. (verify using audio)
Type the characters you see in the picture above; if you can't read them, submit the form and a new image will be generated. Not case sensitive.