source: spip-zone/_plugins_/indexer/trunk/Sources/SpipSourcesIndexer.php @ 87835

Last change on this file since 87835 was 87835, checked in by cam.lafit@…, 5 years ago

Continuer l'indexation au bon endroit selon la source chargée

  • les *part* sont spécifiques à une source

Les compteurs doivent être différenciés et commencer à 0 lors du passage d'une source à l'autre

File size: 6.8 KB
Line 
1<?php
2
3namespace Spip\Indexer\Sources;
4
5use \Indexer\Indexer;
6use \Indexer\Sources\Sources;
7
8class SpipSourcesIndexer {
9
10    /** @var \Indexer\Indexer */
11    private $indexer = null;
12
13    /** @var \Indexer\Sources\Sources */
14    private $sources = null;
15
16    /** @var bool Tables de liens présentes (spip 3 ?) */
17    private $tables_liens = true;
18
19    /** @var string clé de config */
20    private $meta_stats = 'indexer/indexing/stats';
21
22    /**
23     *
24     *
25     * @param \Indexer\Indexer $indexer
26     * @param \Indexer\Sources\Sourcesr $sources
27    **/
28    public function __construct(Indexer $indexer, Sources $sources) {
29        $this->indexer = $indexer;
30        $this->sources = $sources;
31    }
32
33
34    public function setTablesLiensAuto() {
35        include_spip('inc/plugin');
36        $liens = spip_version_compare($GLOBALS['spip_version_branche'], '3.0', '>=');
37        $this->setTablesLiens($liens);
38    }
39
40    public function setTablesLiens($bool) {
41        $this->tables_liens = (bool)$bool;
42    }
43
44
45
46    public function isTimeout() {
47        static $timeout = null;
48
49        if (is_null($timeout)) {
50            include_spip('base/upgrade');
51            if (defined('_TIME_OUT')) {
52                $timeout = _TIME_OUT;
53            } else {
54                $timeout = time() + _UPGRADE_TIME_OUT;
55            }
56        }
57
58        return time() >= $timeout;
59    }
60
61    public function initTimeout() {
62        $this->isTimeout(); // le premier lancement initialise les temps
63    }
64
65
66    public function loadIndexesStats() {
67        include_spip('inc/config');
68        $stats = lire_config($this->meta_stats, array());
69        if (!is_array($stats)) {
70            $stats = array();
71        }
72        return $stats + array(
73            'last' => array(
74                'sourceClass' => '',
75                'source'      => 0,
76                'part'        => array(),
77                'documents'   => 0,
78                'time' => array(
79                    'documents'   => 0,
80                    'indexing'    => 0,
81                ),
82            ),
83            'sources' => array(),
84        );
85    }
86
87    public function loadIndexesStatsClean() {
88        $stats = $this->loadIndexesStats();
89        $stats['last']['documents'] = 0;
90        $stats['last']['time'] = array(
91            'documents'   => 0,
92            'indexing'    => 0,
93        );
94        return $stats;
95    }
96
97    public function saveIndexesStats($stats) {
98        include_spip('inc/config');
99        ecrire_config($this->meta_stats, $stats);
100    }
101
102    public function resetIndexesStats() {
103        include_spip('inc/config');
104        effacer_config($this->meta_stats);
105    }
106
107
108    /**
109     * Indexe toutes les sources en prenant en compte le timeout
110     */
111    public function indexAll() {
112
113        $this->initTimeout();
114
115        $stats = $this->loadIndexesStatsClean();
116        $this->resetIndexesStats();
117
118        $sources = $this->sources->getIterator();
119        // se replacer à la dernière source renseignée (cas d'une indexation non terminée)
120        if ($stats['last']['source']) {
121            $sources->seek($infos['last']['source']);
122        }
123
124        while ($sources->valid()) {
125            $skey    = $sources->key();
126            $source  = $sources->current();
127
128            $stats['last']['source'] = $skey;
129            $stats['last']['sourceClass'] = (string)$source;
130
131            if (!isset($stats['sources'][$skey])) {
132                $stats['sources'][$skey] = array(
133                    'sourceClass' => (string)$source,
134                    'documents' => 0,
135                    'time' => array(
136                        'documents' => 0,
137                        'indexing' => 0,
138                        'total' => 0
139                    )
140                );
141            }
142
143            $this->indexSource($source, $skey, $stats);
144
145            if ($this->isTimeout()) {
146                break;
147            }
148
149            $sources->next();
150        }
151
152        if ($this->isTimeout()) {
153            $this->saveIndexesStats($stats);
154            return false;
155        }
156
157        $this->resetIndexesStats();
158        return $stats;
159    }
160
161
162
163    private function indexSource($source, $skey, &$stats) {
164
165        $source->setTablesLiens($this->tables_liens); // pour SPIP 2.1
166
167        echo "<h2>Analyse de $source :</h2>\n";
168        spip_timer('source');
169
170        // on découpe les documents de cette sources en parts d'un certain nombre
171        // afin d'éviter un timeout et une surcharge mémoire
172        $parts = new \ArrayIterator($source->getParts(1000));
173
174        // on se replace à la dernière part renseignée (cas d'une indexation non terminée)
175        if (isset($stats['last']['part'][$skey]) && $stats['last']['part'][$skey] > 0) {
176            $parts->seek($stats['last']['part'][$skey]);
177        }
178
179        while ($parts->valid()) {
180            $part = $parts->current();
181            $stats['last']['part'][$skey] = $parts->key();
182
183            // on regarde s'il reste du temps AVANT d'indexer les 1000 suivants
184            if ($this->isTimeout()) {
185                $t = spip_timer('source', true);
186                $stats['sources'][$skey]['time']['total'] += $t;
187                return false;
188            }
189
190            $this->indexSourcePart($source, $skey, $part, $stats);
191            $parts->next();
192        }
193
194        echo "<hr /><strong>Temps pour $source :</strong><br />";
195        $t = spip_timer('source', true);
196        $stats['sources'][$skey]['time']['total'] += $t;
197        echo $this->getNiceTime( $stats['sources'][$skey]['time']['total'] );
198    }
199
200
201
202    private function indexSourcePart($source, $skey, $part, &$stats) {
203
204        spip_timer('documents');
205        $documents = $source->getDocuments($part['start'], $part['end']);
206        $t = spip_timer('documents', true);
207        $nb = count($documents);
208
209        $stats['last']['documents'] += $nb;
210        $stats['last']['time']['documents'] += $t;
211
212        $stats['sources'][$skey]['documents'] += $nb;
213        $stats['sources'][$skey]['time']['documents'] += $t;
214
215        if ($nb) {
216            echo "<br /><strong>Temps pour indexer $nb documents (ids $part[start] à $part[end])</strong>\n";
217            echo "<br />Documents: " . $this->getNiceTime($t) . "\n";
218
219            spip_timer('indexing');
220            $this->indexer->replaceDocuments($documents);
221            $t = spip_timer('indexing', true);
222
223            $stats['last']['time']['indexing'] += $t;
224            $stats['sources'][$skey]['time']['indexing'] += $t;
225            echo "<br />Enregistrement dans l'index: " . $this->getNiceTime($t) . "\n";
226        }
227    }
228
229
230
231    /** Retourne un temps formaté pour une belle lecture */
232    public function getNiceTime($p) {
233        if ($p < 1000)
234            $s = '';
235        else {
236            $s = sprintf("%d ", $x = floor($p/1000));
237            $p -= ($x*1000);
238        }
239        return $s . sprintf($s?"%07.3f ms":"%.3f ms", $p);
240    }
241}
Note: See TracBrowser for help on using the repository browser.