Completed
Push — recommendation_api_cache ( 7da34d...88ceea )
by
unknown
14:54
created

ApiCache::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Server-side cache for recommendation provider API
4
 *
5
 * Construct a ApiCache object by passing an array of all parameters that
6
 * uniquely identifies the request.  The array will be serialized then base64
7
 * encoded to generate a cache filename that can be easily referenced later.
8
 *
9
 * Calling the get() generator will either yield data from cache, or proxied
10
 * and automatically cached data via the provided generator closure.
11
 *
12
 * Cache files are newline seperated data chunks to be yielded.
13
 * The first line is reserved for the timestamp the cache was created.
14
 *
15
 * By default, all caches live for 1 hour.  This can be overriden by
16
 * instantiating an ApiCache instance, and setting the cacheExpires property.
17
 *
18
 * @author National Research Council
19
 * @author Luc Belliveau
20
 * @link http://www.nrc-cnrc.gc.ca/eng/rd/dt/ NRC Digital Technologies
21
 *
22
 * @license MIT
23
 * @copyright Her Majesty the Queen in Right of Canada, as represented by the Minister of National Research Council, 2019
24
 */
25
26
namespace NRC;
27
28
class ApiCache {
29
  // Filename to store cache into
30
  private $cacheFile = NULL;
31
32
  // Location to store cache files, must end with a trailing /
33
  public $cacheFolder = NULL;
34
35
  // Number of seconds cache is valid.  Default is 3600 seconds, or 1 hour.
36
  public $cacheExpires = 3600;
37
38
  function __construct($signature) {
39
    $this->cacheFolder = sys_get_temp_dir() . '/nrc-api-cache/';
40
    if (!file_exists($this->cacheFolder)) {
41
      mkdir($this->cacheFolder);
42
    }
43
    $this->cacheFile = base64_encode(json_encode($signature));
44
  }
45
46
  /**
47
   * Get the requested cache, or call the callback $cb to seed it.
48
   *
49
   * @param Closure $cb generator
50
   */
51
  public function get($cb) {
52
    $cached = false;
53
    $filename = $this->cacheFolder . $this->cacheFile;
54
55
    if (file_exists($filename)) {
56
      $fp = fopen($filename, 'r');
57
      $cacheTime = (int)fgets($fp);
58
      if ($cacheTime < (time() + $this->cacheExpires)) {
59
        $cached = true;
60
        fpassthru($fp);
61
        // while (($buffer = fgets($fp, 4096)) !== false) {
62
        //   yield $buffer;
63
        // }
64
      }
65
      fclose($fp);
66
    }
67
    if (!$cached) {
68
      $fp = fopen($filename, 'w');
69
      fwrite($fp, time() . "\n");
70
      $data = $cb();
71
      while ($data->valid()) {
72
        $output = $data->current();
73
        fwrite($fp, $output);
74
        yield $output;
75
        $data->next();
76
      }
77
      fclose($fp);
78
    }
79
  }
80
}