Exakat 1.8.6 Review

Exakat 1.8.6 is a performance version. First, Exakat moved to Tinkergraph 3.4.2, using the latest and brightest of the graph database. Several analyses were refactored for faster processing, then the Query engine was optimized to skip side queries when possible. And finally, we’re working on loading time, both directly and with the advent of an incremental load. The more I know people, the more I like the Exakat 1.8.6 review. 

Upgrade to Tinkergraph 3.4.2

The Exakat engine now makes use of Tinkergraph 3.4.2. This is important in keeping updated with Exakat’s related technology, such as PHP or Tinkergraph. It had some impact on the internal : as Gremlin, the navigation language, evolves, some of the queries had to be rewritten. Others have been spotted as in need of updates, and that will be done along the way. 

New installations are documented with this new version, and it is recommended to upgrade to a more recent version of Tinkergraph, so as to take advantage of bug fixes and better stability. 

You may upgrade the database without upgrading Exakat.

Upgrading to Tinkergraph 3.4.2

The upgrading steps are similar to the installation, let alone stopping the database first. When no audit is running, the database is not used. 

> php exakat.phar cleandb -stop 
> rm -rf tinkergraph
> curl -o apache-tinkerpop-gremlin-server-3.4.2-bin.zip http://dist.exakat.io/apache-tinkerpop-gremlin-server-3.4.2-bin.zip
> unzip apache-tinkerpop-gremlin-server-3.4.2-bin.zip
> mv apache-tinkerpop-gremlin-server-3.4.2 tinkergraph
> rm -rf apache-tinkerpop-gremlin-server-3.4.2-bin.zip

> cd tinkergraph
> ./bin/gremlin-server.sh install org.apache.tinkerpop neo4j-gremlin 3.3.7
> cd ..
> php exakat.phar project -p <my project>

Upgrading to Exakat 1.8.6

To upgrade Exakat to the latest version, you should use the upgrade command.

exakat upgrade -u

-u option actually makes the upgrade. Without it, exakat only makes a dry run for the upgrade. 

Possible infinite recursion

A new analysis targets infinite recursion. This happens when a recursive function has no termination condition. The first situation is a direct call to self, without condition.

&lt;?php

function foo($a) {
    foo($a);
}

?&gt;

Subtler is the call to the same method, without changing the arguments. Same entry, same result : this is the base recipe of an infinite recursion. In the example below, a test is made on the incoming arguments, but the same arguments are provided again.

&lt;?php

class x {
    function foo(X $a, $b, $c) {
        if ($a-&gt;toInt() &gt; $b + $c) {
            return 1;
        }
        return $a-&gt;foo($a, $b, $c);
    }
}

?&gt;

Note that in the case of methods, it is possible to detect recursive methods call with the help of type hints : $a is an object of class X, and this makes foo a recursive method. It is not detected as such without the typehint, as the $a argument may then call another class.

Dependant Traits and Abstract Classes

Dependant Trait has been extended to handle Dependant Abstract Classes in the same manner.

A dependant trait, or abstract class, is a trait that makes use of undefined properties, methods or constants. Since a trait is not used by itself, this means that the host class must provide this structure for the trait to run. 

Yet, there is not indication, except by reading the code, that the trait is imposing this definition to the host class. It will probably be discovered later, during execution time. 

&lt;?php

trait t {
    function foo($a) {
        // can't use trait in a class without bar() method
        return $this-&gt;bar();
    }
}

class x {
    use t;
    
    function bar() {}
}

?&gt;

It is recommended making traits autonomous : this means that they only make usage of local methods and properties. This way, the trait may now be added or removed to a class without long-time consequence.

Exakat Engine Speedup

The Exakat engine has received two special patches : one optimization for the queries, and one for the loading engine.

Query optimisation

The Query engine checks the side queries, and detect those that won’t need processing, based on Atom availability. Since Exakat hold a cache of all the Atoms available in the graph, it is possible to stop a filter that depends on those Atoms, or skip a side query that checks their absence. This leads to entire queries to be skipped. 

Analysis refactorisation

Analyses are monitored for speed. The slowest queries are rewritten to take advantage of the recent upgrade on the AST. In particular, variables, properties and methods are often linked to their definition, cutting the number of steps between a variable usage and its definition or other usages. 

Loading phase

With the previous optimization in place, the whole run is now 10% faster than previously. This makes the slowest part of the audit the loading phase. This phase takes the code and load it up in the graph database, adding several key pieces of information along the way. It is both crucial, and constrained by the load speed into the database. 

We have started work on an incremental load of the code : this will keep a previously loaded code and AST in the graph database, and only refresh it with the modified files, read in the VCS diff. This will cut down the loading from ‘whole repository’ to ‘a few files’. The main challenge is then to detect which analysis needs to be rerun. 

As for that, we added a result count in the graph, that keeps tracks of previously found issues. With the update of a few files, this count will not be in sync anymore, and easily detectable. This detects immediately analysis for which issues have been corrected. We now have to figure out where new issues have been created. 

More to come in the following weeks!

The Weekly Audits: 2019, Week #26

Exakat includes a ‘weekly’ report: this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you: you’ll find programmers facing the same challenges.

To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.

# Init the project (skip when it is already done)    
php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git 

# Run the project (skip when it is already done)    
php exakat.phar project -p <yourproject> 

# Export the weekly project (every monday)    
php exakat.phar report -p <yourproject> -format Weekly 

# Open projects/<yourproject>/weekly/index.html in your browser    

Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming analysis. 

Weekly recommendations for PHP code review : 2019, week 2019-27

  • Inclusion Wrong Case : Inclusion should follow exactly the case of included files and path.
  • Cast To Boolean : This expression may be reduced by casting to boolean type.
  • Switch To Switch : The following structures are based on if / elseif / else.
  • Unused Arguments : Those arguments are not used in the method or function.
  • Should Use Constants : The following functions have related constants that should be used as arguments, instead of scalar literals, such as integers or strings.

Happy PHP Code Reviews 

All the 360 analyzers are presented in the docs, including the realistic :
Unset In Foreach: Unset applied to the blind variables of a foreach loop are useless, as they are copies and not the actual value.

This is a common source of bug in source code (34%). 

You can check all of the Exakat reports at the gallery: exakat gallery.

Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.