Cannot activate extension on Memcache+WP configuration
This issue was originally reported by @haystack on Mattermost and described further in the comments for a PR for #316 (closed). It is similar to #316 (closed) in that both involve a Memcache configuration, but otherwise it appears different. (I have not personally been able to reproduce it yet, and the solution for #316 (closed) doesn't address this.) Below, I'm copying over the details from Christian's previous report.
Excerpt 1
(From Christian)
One further issue I've run into is that Extensions cannot be installed while Memcached is being used:
$Fatal Error Details = array(3) {
["message"]=>
string(19) "Unknown extension: "
["code"]=>
NULL
["exception"]=>
object(CRM_Extension_Exception_MissingException)#6982 (10) {
["errorData":"CRM_Core_Exception":private]=>
array(1) {
["error_code"]=>
int(0)
}
... lots more debugging ...
As you can see, $key
is empty in CRM_Extension_Container_Collection::getContainer()
- I presume this is as a result of CRM_Extension_Container_Collection::getKeysToContainer()
grabbing the containers with:
$k2c = $this->cache->get($this->cacheKey);
FWIW, turning Memcached off allows me to install Extensions.
Excerpt 2
(From Christian)
Apologies in advance if there's too much debugging info below - I've tried to debug the Install Extension process but I get lost in the intricacies of HTML_QuickForm
so I thought dumping everything I can see might help. The problem in CRM_Extension_Container_Collection::getContainer()
is that $key
is not defined:
Array
(
[method] => CRM_Extension_Container_Collection::getContainer
[key] =>
[k2c] => Array
(
[com.iatspayments.civicrm] => civiroot
[org.civicrm.shoreditch] => default
)
[backtrace] => #0 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Extension/Container/Collection.php(111): CRM_Extension_Container_Collection->getContainer(NULL)
#1 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Extension/Mapper.php(185): CRM_Extension_Container_Collection->getPath(NULL)
#2 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Admin/Form/Extensions.php(85): CRM_Extension_Mapper->keyToInfo(NULL)
#3 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Form.php(585): CRM_Admin_Form_Extensions->preProcess()
#4 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/StateMachine.php(136): CRM_Core_Form->buildForm()
#5 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/QuickForm/Action/Next.php(61): CRM_Core_StateMachine->perform(Object(CRM_Admin_Form_Extensions), 'next', 'Next')
#6 /path/to/wp-content/plugins/civicrm/civicrm/packages/HTML/QuickForm/Controller.php(203): CRM_Core_QuickForm_Action_Next->perform(Object(CRM_Admin_Form_Extensions), 'next')
#7 /path/to/wp-content/plugins/civicrm/civicrm/packages/HTML/QuickForm/Page.php(103): HTML_QuickForm_Controller->handle(Object(CRM_Admin_Form_Extensions), 'next')
#8 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Controller.php(351): HTML_QuickForm_Page->handle('next')
#9 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Page/Basic.php(398): CRM_Core_Controller->run()
#10 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Page/Basic.php(156): CRM_Core_Page_Basic->edit(1, NULL)
#11 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Admin/Page/Extensions.php(121): CRM_Core_Page_Basic->run()
#12 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Invoke.php(309): CRM_Admin_Page_Extensions->run(Array, NULL)
#13 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Invoke.php(84): CRM_Core_Invoke::runItem(Array)
#14 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Invoke.php(52): CRM_Core_Invoke::_invoke(Array)
#15 /path/to/wp-content/plugins/civicrm/civicrm.php(1246): CRM_Core_Invoke::invoke(Array)
#16 [internal function]: CiviCRM_For_WordPress->invoke('')
#17 /path/to/wp-includes/class-wp-hook.php(286): call_user_func_array(Array, Array)
#18 /path/to/wp-includes/class-wp-hook.php(310): WP_Hook->apply_filters('', Array)
#19 /path/to/wp-includes/plugin.php(453): WP_Hook->do_action(Array)
#20 /path/to/wp-admin/admin.php(224): do_action('toplevel_page_C...')
#21 {main}
)
Debugging further up the line in CRM_Admin_Form_Extensions::preProcess()
shows the context, though it still doesn't show me exactly why $key
is undefined:
Array
(
[method] => CRM_Admin_Form_Extensions::preProcess
[key] =>
[id] =>
[GET] => Array
(
[page] => CiviCRM
[q] => civicrm/admin/extensions
[noheader] => 1
)
[POST] => Array
(
[qfKey] => 926b1c386f5b9c64184e995104741f62_6496
[_qf_default] => Extensions:next
[_qf_Extensions_next] => Install
)
[REQUEST] => Array
(
[page] => CiviCRM
[q] => civicrm/admin/extensions
[noheader] => 1
[qfKey] => 926b1c386f5b9c64184e995104741f62_6496
[_qf_default] => Extensions:next
[_qf_Extensions_next] => Install
)
[backtrace] => #0 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Form.php(585): CRM_Admin_Form_Extensions->preProcess()
#1 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/StateMachine.php(136): CRM_Core_Form->buildForm()
#2 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/QuickForm/Action/Next.php(61): CRM_Core_StateMachine->perform(Object(CRM_Admin_Form_Extensions), 'next', 'Next')
#3 /path/to/wp-content/plugins/civicrm/civicrm/packages/HTML/QuickForm/Controller.php(203): CRM_Core_QuickForm_Action_Next->perform(Object(CRM_Admin_Form_Extensions), 'next')
#4 /path/to/wp-content/plugins/civicrm/civicrm/packages/HTML/QuickForm/Page.php(103): HTML_QuickForm_Controller->handle(Object(CRM_Admin_Form_Extensions), 'next')
#5 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Controller.php(351): HTML_QuickForm_Page->handle('next')
#6 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Page/Basic.php(398): CRM_Core_Controller->run()
#7 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Page/Basic.php(156): CRM_Core_Page_Basic->edit(1, NULL)
#8 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Admin/Page/Extensions.php(121): CRM_Core_Page_Basic->run()
#9 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Invoke.php(309): CRM_Admin_Page_Extensions->run(Array, NULL)
#10 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Invoke.php(84): CRM_Core_Invoke::runItem(Array)
#11 /path/to/wp-content/plugins/civicrm/civicrm/CRM/Core/Invoke.php(52): CRM_Core_Invoke::_invoke(Array)
#12 /path/to/wp-content/plugins/civicrm/civicrm.php(1246): CRM_Core_Invoke::invoke(Array)
#13 [internal function]: CiviCRM_For_WordPress->invoke('')
#14 /path/to/wp-includes/class-wp-hook.php(286): call_user_func_array(Array, Array)
#15 /path/to/wp-includes/class-wp-hook.php(310): WP_Hook->apply_filters('', Array)
#16 /path/to/wp-includes/plugin.php(453): WP_Hook->do_action(Array)
#17 /path/to/wp-admin/admin.php(224): do_action('toplevel_page_C...')
#18 {main}
)
Here's what CRM_Admin_Form_Extensions
looks like at the above moment:
[this] => CRM_Admin_Form_Extensions Object
(
[_id:protected] =>
[_values:protected] => Array
(
)
[_BAOName:protected] => CRM_Core_BAO_Extension
[_state:protected] =>
[_name:protected] => Extensions
[_title:protected] =>
[_defaults] => Array
(
)
[_options] =>
[_action] => 1
[_paymentProcessors:protected] =>
[_paymentProcessorIDs] =>
[_paymentProcessorID:protected] =>
[_is_pay_later_enabled:protected] =>
[_renderer:protected] =>
[_dateFields:protected] => Array
(
)
[unsavedChangesWarn:protected] =>
[ajaxResponse] => Array
(
)
[urlPath] => Array
(
[0] => civicrm
[1] => admin
[2] => extensions
)
[context:protected] =>
[controller] => CRM_Core_Controller_Simple Object
(
[_title:protected] => CRM_Admin_Form_Extensions
[_key] => 926b1c386f5b9c64184e995104741f62_6496
[_scope:protected] => CRM_Admin_Form_Extensions_926b1c386f5b9c64184e995104741f62_6496
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
[_embedded:protected] => 1
[_skipRedirection:protected] =>
[_print] => 0
[_generateQFKey] => 1
[_QFResponseType] => html
[_parent:protected] =>
[_destination] =>
[_entryURL] =>
[_pages] => Array
(
[Extensions] => CRM_Admin_Form_Extensions Object
*RECURSION*
)
[_actions] => Array
(
[Extensions] => HTML_QuickForm_Action_Direct Object
(
)
[display] => CRM_Core_QuickForm_Action_Display Object
(
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
)
[next] => CRM_Core_QuickForm_Action_Next Object
(
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
)
[back] => CRM_Core_QuickForm_Action_Back Object
(
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
)
[process] => CRM_Core_QuickForm_Action_Process Object
(
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
)
[cancel] => CRM_Core_QuickForm_Action_Cancel Object
(
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
)
[refresh] => CRM_Core_QuickForm_Action_Refresh Object
(
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
)
[reload] => CRM_Core_QuickForm_Action_Reload Object
(
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
)
[done] => CRM_Core_QuickForm_Action_Done Object
(
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
)
[jump] => CRM_Core_QuickForm_Action_Jump Object
(
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
)
[submit] => CRM_Core_QuickForm_Action_Submit Object
(
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
)
[upload] => CRM_Core_QuickForm_Action_Upload Object
(
[_uploadNames:protected] => Array
(
[0] => attachFile_1
[1] => attachFile_2
[2] => attachFile_3
[3] => uploadFile
)
[_uploadDir:protected] => /path/to/wp-content/plugins/files/civicrm/upload/
[_stateMachine:protected] => CRM_Core_StateMachine Object
(
[_controller:protected] => CRM_Core_Controller_Simple Object
*RECURSION*
[_states:protected] => Array
(
[Extensions] => CRM_Core_State Object
(
[_name:protected] => Extensions
[_type:protected] => 3
[_back:protected] =>
[_next:protected] =>
[_stateMachine:protected] => CRM_Core_StateMachine Object
*RECURSION*
)
)
[_pages:protected] => Array
(
[CRM_Admin_Form_Extensions] =>
)
[_pageNames:protected] => Array
(
[0] => Extensions
)
[_action:protected] => 0
[_name:protected] =>
)
)
)
[_name] => CRM_Admin_Form_Extensions_926b1c386f5b9c64184e995104741f62_6496
[_modal] => 1
[_actionName] => Array
(
[0] => Extensions
[1] => next
)
)
[_chainSelectFields:CRM_Core_Form:private] => Array
(
)
[_actions] => Array
(
)
[_formBuilt] => 1
[_elements] => Array
(
)
[_elementIndex] => Array
(
)
[_duplicateIndex] => Array
(
)
[_required] => Array
(
)
[_jsPrefix] => Invalid information entered.
[_jsPostfix] => Please correct these fields.
[_datasource] =>
[_defaultValues] => Array
(
)
[_constantValues] => Array
(
)
[_submitValues] => Array
(
[qfKey] => 926b1c386f5b9c64184e995104741f62_6496
[_qf_default] => Extensions:next
[_qf_Extensions_next] => Install
)
[_submitFiles] => Array
(
)
[_maxFileSize] => 41943040
[_freezeAll] =>
[_rules] => Array
(
)
[_formRules] => Array
(
)
[_errors] => Array
(
)
[_requiredNote] => <span style="font-size:80%; color:#ff0000;">*</span><span style="font-size:80%;"> denotes required field</span>
[_flagSubmitted] => 1
[_attributes] => Array
(
[action] => https://domain.org/wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/extensions
[method] => post
[name] => Extensions
[id] => Extensions
[class] => CRM_Admin_Form_Extensions
)
[_tabOffset] => 0
[_tab] =>
[_lineEnd] =>
[_comment] =>
[_key] =>
)
So, somewhere at some point, the _key
property is not being set.
@totten Can you suggest how I might be able to pinpoint what's going on?
Excerpt 3
(From Christian)
@totten A little more info: when Memcached is not being used, the URL sequence is as follows:
- The "Install" page is: https://domain.org/wp-admin/admin.php?page=CiviCRM&q=civicrm%2Fadmin%2Fextensions&action=add&id=org.civicrm.shoreditch&key=org.civicrm.shoreditch
- The resulting location is: https://domain.org/wp-admin/admin.php?page=CiviCRM&q=civicrm%2Fadmin%2Fextensions&reset=1&action=browse
When Memcached is being used:
- The "Install" page is: https://domain.org/wp-admin/admin.php?page=CiviCRM&q=civicrm%2Fadmin%2Fextensions&action=add&id=org.civicrm.shoreditch&key=org.civicrm.shoreditch
- The resulting location is: https://domain.org/wp-admin/admin.php?page=CiviCRM&q=civicrm%2Fadmin%2Fextensions
As I said, I'll happily test further given pointers as to where to keep digging.
Excerpt 4
(From totten via Mattermost)
@haystack on a brief skim, it seems like the target extension-key should be passed through page arguments, but the pageflow there is a little tricky (so brief skim may be miselading). Maybe a quirk in session-mgmt could be the issue? (Ex: memcache prematurely purges session-state). Would be interesting to see:
- With memcache active -- do the extensions install via CLI? (e.g.
wp civicrm-api extension.install key=org.civicrm.shoreditch
orcv en shoreditch
) - With memcache active -- does the gui installer work when if sessions are stored in sql - but otherwise the system uses memcache ?
If #2 (closed) works, I'd take that as a signal that memcache isn't reliably storing session state.
If #2 (closed) doesn't make a difference, then #1 (closed) might be interesting.