1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Fixed xf_deferred: Data too long for column 'unique_key'

Discussion in 'Resolved Bug Reports' started by Chris D, Sep 11, 2013.

  1. Chris D

    Chris D XenForo Developer Staff Member

    The unique_key column in xf_deferred is VARBINARY(50)

    My deferred class name happens to be 47 characters long and actionTriggerDeferred simply passes Rebuild + Class_Name to the defer method as the unique key:

    PHP:
    XenForo_Application::defer($input['cache'], $input['options'], 'Rebuild' $input['cache'], true);
    It would be nice to see:

    PHP:
            $input $this->_input->filter(array(
                
    'cache' => XenForo_Input::STRING,
                
    'options' => XenForo_Input::ARRAY_SIMPLE,
                
    'unique_key' => XenForo_Input::STRING
            
    ));

            if (
    $input['cache'])
            {
                if (!
    $input['unique_key'])
                {
                    
    $input['unique_key'] = 'Rebuild_' $input['cache'];
                }

                
    $obj XenForo_Deferred_Abstract::create($input['cache']);
                if (
    $obj)
                {
                    
    XenForo_Application::defer($input['cache'], $input['options'], $input['unique_key'], true);
                }
            }
    So we can specify our own unique_key via a hidden input or, quite simply a change of the column definition to be, at least, VARBINARY(100) :)
     
    Adam Howard and Bob like this.
  2. Chris D

    Chris D XenForo Developer Staff Member

    Strictly speaking, of course, specifying a custom unique key and the current method, produces something that isn't a unique key.

    And, unfortunately, doesn't this potentially result in another error?

    What if two Admins were to rebuild the same cache at the same time. The unique_key column has a unique index on the table, and in that scenario the unique_key would not be unique.

    I nearly suggested it last night. But I think I will now, anyway.

    What if the unique_key was:

    PHP:
            $input $this->_input->filter(array(
                
    'cache' => XenForo_Input::STRING,
                
    'options' => XenForo_Input::ARRAY_SIMPLE
            
    ));

            if (
    $input['cache'])
            {
                
    $uniqueKey uniqid('Rebuild_');
                
    $uniqueKey substr($uniqueKey $input['cache'], 050);

                
    $obj XenForo_Deferred_Abstract::create($input['cache']);
                if (
    $obj)
                {
                    
    XenForo_Application::defer($input['cache'], $input['options'], $uniqueKeytrue);
                }
            }
    So we generate a unique ID in PHP with a prefix of Rebuild_ then add the cache name (or class name) to it and substr it down to the first 50 characters.

    You wouldn't need to change the database column definition, and unique_id would ultimately become actually unique.
     
  3. Mike

    Mike XenForo Developer Staff Member

    It does an INSERT ON DUPLICATE KEY UPDATE. The second request would override the first (if I remember the code correctly). This is used in situations where running the same thing twice (back to back) doesn't have a benefit.
     
    Chris D likes this.
  4. Chris D

    Chris D XenForo Developer Staff Member

    Actually, yes, I can confirm that.

    So it wouldn't trigger an error.

    Still might be a good solution, though, to resolve the data too long error. Unless you prefer to just increase the column limit... Or I could just use shorter class names (which I have done in this case :p)
     
  5. Mike

    Mike XenForo Developer Staff Member

    I've just flipped it to switching to a hashing mechanism on the unique key if the length is too long.
     
    Chris D likes this.

Share This Page