Artifact pull code improvements
This replaces Element.__pull_strong() and Element.__pull_weak() with Artifact.pull(). Besides simplifying code in element.py, this removes the call to _pull_done() from the job process, which would cause issues with the upcoming thread-based scheduler !1982 (merged).
This also fixes ArtifactCache.link_key() to update the reference if it exists already. We want the weak reference to point to the most recent artifact with the same weak cache key, not the oldest. This revealed a bug in ArtifactElement, which is fixed in this branch as well.