<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "http://pkp.sfu.ca/bugzilla/bugzilla.dtd">

<bugzilla version="4.2.5+"
          urlbase="http://pkp.sfu.ca/bugzilla/"
          
          maintainer="pkp-hosted@sfu.ca"
>

    <bug>
          <bug_id>8129</bug_id>
          
          <creation_ts>2013-02-22 10:23:00 -0800</creation_ts>
          <short_desc>Referral plugin prone to race conditions</short_desc>
          <delta_ts>2013-03-25 15:10:02 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>OJS</product>
          <component>Plug-ins</component>
          <version>2.4.3</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P3</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Alec Smecher">alec</reporter>
          <assigned_to name="PKP Support">pkp-support</assigned_to>
          <cc>michael.thessel</cc>
          
          

      

      

      

          <long_desc isprivate="0">
            <commentid>33439</commentid>
            <who name="Alec Smecher">alec</who>
            <bug_when>2013-02-22 10:23:00 -0800</bug_when>
            <thetext>Currently the referral plugin checks to see if a referral exists, then if not, inserts it. This is prone to race conditions, e.g. two simultaneous-ish requests for the same article from the same URL will lead one to respond with a duplicate entry on index error from MySQL.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>33834</commentid>
            <who name="Michael Thessel">michael.thessel</who>
            <bug_when>2013-03-19 10:27:59 -0700</bug_when>
            <thetext>Currently the primary key for the referrals table is referral_id. article_id and url have a UNIQUE constraint. We could change the primary key to url and article_id and use REPLACE INTO when inserting a new referral. This way we should be able to avoid race conditions. Based on how the referral system works I would still keep the referral_id (auto_increment, unique). 

To do so we would need to change the schema of that table. I&apos;m not sure how you handle schema changes during upgrades. Could you please point me in the right direction?

mysql&gt; explain referrals;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| referral_id | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| article_id  | bigint(20)   | NO   | MUL | NULL    |                |
| status      | smallint(6)  | NO   |     | NULL    |                |
| url         | varchar(255) | NO   |     | NULL    |                |
| date_added  | datetime     | NO   |     | NULL    |                |
| link_count  | bigint(20)   | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>33846</commentid>
            <who name="Alec Smecher">alec</who>
            <bug_when>2013-03-19 14:05:12 -0700</bug_when>
            <thetext>Michael, I&apos;d suggest avoiding schema changes for the moment; the change of indexes wouldn&apos;t be material for the race condition fix (if I understand you correctly). You shouldn&apos;t use REPLACE INTO directly in your SQL because PostgreSQL doesn&apos;t support it; you might be able to use ADODB&apos;s Replace() function instead, but in that case, be careful you don&apos;t clobber e.g. date_added and link_count if you do.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>33875</commentid>
            <who name="Michael Thessel">michael.thessel</who>
            <bug_when>2013-03-21 10:41:18 -0700</bug_when>
            <thetext>I was planning on changing the primary key to be able to use MySQL&apos;s REPLACE INTO. This fix would work on MySQL. You are right though, REPLACE INTO is native to MySQL and won&apos;t work with PostgreSQL. I will look for a different solution.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>33879</commentid>
            <who name="Michael Thessel">michael.thessel</who>
            <bug_when>2013-03-21 11:34:36 -0700</bug_when>
            <thetext>I added a pull request with a proposed fix to GITHub. It utilizes the ADODB replace() function for inserts. The referral plugin checks if the URL already exists before calling insertReferral(). This will prevent issues like resetting the date or the link count.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>33893</commentid>
            <who name="Michael Thessel">michael.thessel</who>
            <bug_when>2013-03-22 09:09:00 -0700</bug_when>
            <thetext>I added the requested function name changes to the pull request.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>33954</commentid>
            <who name="Michael Thessel">michael.thessel</who>
            <bug_when>2013-03-25 14:55:02 -0700</bug_when>
            <thetext>Renamed function to reflect new functionality
https://github.com/pkp/ojs/commit/936b78b11ba0bf89e2022a2830d022994e687163</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>33955</commentid>
            <who name="Michael Thessel">michael.thessel</who>
            <bug_when>2013-03-25 14:55:02 -0700</bug_when>
            <thetext>Whitespace cleanup
https://github.com/pkp/ojs/commit/1607437f27b4689d994a07d08d06fe300bb79857</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>33956</commentid>
            <who name="Alec Smecher">alec</who>
            <bug_when>2013-03-25 15:10:02 -0700</bug_when>
            <thetext>Race condition in referral plugin insert
https://github.com/pkp/ojs/commit/185b208fe6dc7fedb683b00adfaa077c4ec5a882</thetext>
          </long_desc>
      
      

    </bug>

</bugzilla>