PageRenderTime 35ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/guides/hhvm/03-advanced-usage/02-repo-authoritative.md

https://gitlab.com/Blueprint-Marketing/user-documentation
Markdown | 77 lines | 50 code | 27 blank | 0 comment | 0 complexity | dc1a2cbe26cf39f17418d93cae839ab1 MD5 | raw file
  1. In default operation, HHVM behaves like the original PHP engine: it loads and compiles code on-the-fly as it is needed. A `require` of a brand new file can just load up that file and execute it; `eval` can easily summon new subclasses into existence. This gives a lot of flexibility, but can inhibit a lot of potential optimizations.
  2. Repo authoritative mode works differently. You build a bytecode file ahead of time called the *repo* and deploy that file to production instead of the PHP source files. Then the HHVM server process reads from the repo file and never checks for source file changes.
  3. The obvious benefit here is that HHVM doesn't re-read your source files on every request, but this is actually the smallest of the optimizations allowed in repo authoritative mode. Because HHVM can see all of your code when originally generating the repo, and no more code can ever be brought into existence after that, HHVM can do a whole lot of inference about what your code is doing, and optimize based on that. For example, it might notice that when a certain member variable is written to, the value written to it will always be an `int`. (It can do this whether your code is PHP or Hack!) HHVM can then know to allocate an int-sized slot in every instance of that object, and to always generate integer instructions to manipulate that slot, without guarding on the type every time during execution. These optimizations can give a huge performance benefit.
  4. To use repo authoritative mode, you need to build a repo, and then deploy that repo (i.e., configure HHVM to use it). You can either do that via an automatic script, or manually.
  5. ## Automatic Script
  6. If you are using our Debian packages, and have a fairly standard configuration, we provide a shell script to automate building and deploying the repo. If your PHP and Hack source files are under `/path/to/root`, you can run
  7. ```
  8. sudo hhvm-repo-mode enable /path/to/root
  9. ```
  10. to build the repo and enable repo authoritative mode, and you can run
  11. ```
  12. sudo hhvm-repo-mode disable
  13. ```
  14. to disable it again.
  15. ## Manually Building the Repo
  16. ### Everything Under a Root
  17. To build a repo including all files recursively under `/path/to/root`, invoke HHVM like this:
  18. ```
  19. hhvm --hphp -t hhbc -v AllVolatile=true --input-dir /path/to/root
  20. ```
  21. Flag | Description
  22. -----|------------
  23. `--hphp` | Signals to HHVM that we are doing an offline operation instead of executing PHP or Hack code.
  24. `-t hhbc` | `t` is for target. `hhbc` is for HHVM Bytecode. So the output of the repo will be HHVM bytecode.
  25. `AllVolatile` | Setting this to `true` disables an aggressive optimization that has the possibility to break code. This probably be the default, but unfortunately is not right now.
  26. `--input-dir` | The directory containing the source files to compile into the repo.
  27. ### Manual List of Files
  28. Instead of a directory, you can also pass it an explicit list of filenames to put in the repo or a master file that contains all of the files, one per line, that should be put in the repo. (Keep in mind that the commands below are generating two *separate* repos -- you can't add to or remove from a repo once it's been generated!)
  29. ```
  30. hhvm --hphp -t hhbc -v AllVolatile=true file1.php file2.php
  31. hhvm --hphp -t hhbc -v AllVolatile=true --input-list master-file-list.txt
  32. ```
  33. The `master-file-list.txt` should look like this:
  34. ```
  35. index.php
  36. src/a.php
  37. src/b.php
  38. lib/c.php
  39. ```
  40. ## Manually Deploying the Repo
  41. After you build the repo, an SQLite3 database file called `hhvm.hhbc` is created. You copy this file to your production server. HHVM will use this file when serving requests and will not need the physical source files.
  42. You must use the same HHVM version to run from the repo as you did to build the repo. In other words, a repo is tied to the version that built it. (Getting this wrong will lead to extremely cryptic errors about missing units in the repo.)
  43. You can put the repo file anywhere as long as these two ini settings are set correctly in your `server.ini` (or equivalent) file.
  44. ```
  45. hhvm.repo.authoritative=true
  46. hhvm.repo.central.path=/path/to/hhvm.hhbc
  47. ```
  48. ## Tradeoffs
  49. The benefits of repo authoritative mode are discussed above: it dramatically increases the scope of the optimizations HHVM can do to your code.
  50. However, the downside to this is that all your code must be visible to HHVM ahead of time. In repo authoritative mode, using a `require` to load new files that are not part of the repo is not allowed. Neither is using functions like [`eval()`](http://php.net/manual/en/function.eval.php) or [`create_function()`](http://php.net/manual/en/function.create-function.php). HHVM cannot dynamically load or run code in repo authoritative mode, since the optimizations rely on seeing all the code during repo build time.