Skip to content

Instantly share code, notes, and snippets.

@heathdutton
Created July 10, 2018 17:01
Show Gist options
  • Save heathdutton/c61d11c58fce60ff37449e97cd18a285 to your computer and use it in GitHub Desktop.
Save heathdutton/c61d11c58fce60ff37449e97cd18a285 to your computer and use it in GitHub Desktop.
5970 to avoid conflicts with others
diff --git a/app/bundles/CampaignBundle/Entity/CampaignRepository.php b/app/bundles/CampaignBundle/Entity/CampaignRepository.php
index 589253a618..5442ca10d5 100644
--- a/app/bundles/CampaignBundle/Entity/CampaignRepository.php
+++ b/app/bundles/CampaignBundle/Entity/CampaignRepository.php
@@ -22,6 +22,7 @@
class CampaignRepository extends CommonRepository
{
use ContactLimiterTrait;
+ use SlaveConnectionTrait;
/**
* {@inheritdoc}
@@ -348,7 +349,7 @@ public function getPopularCampaigns($limit = 10)
*/
public function getCountsForPendingContacts($campaignId, array $pendingEvents, ContactLimiter $limiter)
{
- $q = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $q = $this->getSlaveConnection($limiter)->createQueryBuilder();
$q->select('min(cl.lead_id) as min_id, max(cl.lead_id) as max_id, count(cl.lead_id) as the_count')
->from(MAUTIC_TABLE_PREFIX.'campaign_leads', 'cl')
@@ -394,7 +395,7 @@ public function getCountsForPendingContacts($campaignId, array $pendingEvents, C
*/
public function getPendingContactIds($campaignId, ContactLimiter $limiter)
{
- $q = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $q = $this->getSlaveConnection($limiter)->createQueryBuilder();
$q->select('cl.lead_id')
->from(MAUTIC_TABLE_PREFIX.'campaign_leads', 'cl')
@@ -410,7 +411,7 @@ public function getPendingContactIds($campaignId, ContactLimiter $limiter)
$this->updateQueryFromContactLimiter('cl', $q, $limiter);
// Only leads that have not started the campaign
- $sq = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $sq = $this->getSlaveConnection($limiter)->createQueryBuilder();
$sq->select('null')
->from(MAUTIC_TABLE_PREFIX.'campaign_lead_event_log', 'e')
->where(
@@ -449,7 +450,7 @@ public function getPendingContactIds($campaignId, ContactLimiter $limiter)
*/
public function getCampaignLeadCount($campaignId, $leadId = null, $pendingEvents = [], $dateRangeValues = null)
{
- $q = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $q = $this->getSlaveConnection()->createQueryBuilder();
$q->select('count(cl.lead_id) as lead_count')
->from(MAUTIC_TABLE_PREFIX.'campaign_leads', 'cl')
@@ -468,7 +469,7 @@ public function getCampaignLeadCount($campaignId, $leadId = null, $pendingEvents
}
if (count($pendingEvents) > 0) {
- $sq = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $sq = $this->getSlaveConnection()->createQueryBuilder();
$sq->select('null')
->from(MAUTIC_TABLE_PREFIX.'campaign_lead_event_log', 'e')
->where(
@@ -500,7 +501,7 @@ public function getCampaignLeadCount($campaignId, $leadId = null, $pendingEvents
*/
public function getCampaignLeads($campaignId, $start = 0, $limit = false, $select = ['cl.lead_id'])
{
- $q = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $q = $this->getSlaveConnection()->createQueryBuilder();
$q->select($select)
->from(MAUTIC_TABLE_PREFIX.'campaign_leads', 'cl')
diff --git a/app/bundles/CampaignBundle/Entity/LeadEventLogRepository.php b/app/bundles/CampaignBundle/Entity/LeadEventLogRepository.php
index c9282494b1..d7aba37b84 100644
--- a/app/bundles/CampaignBundle/Entity/LeadEventLogRepository.php
+++ b/app/bundles/CampaignBundle/Entity/LeadEventLogRepository.php
@@ -25,6 +25,7 @@ class LeadEventLogRepository extends CommonRepository
{
use TimelineTrait;
use ContactLimiterTrait;
+ use SlaveConnectionTrait;
public function getEntities(array $args = [])
{
@@ -219,7 +220,7 @@ public function getUpcomingEvents(array $options = null)
*/
public function getCampaignLogCounts($campaignId, $excludeScheduled = false, $excludeNegative = true, $dateRangeValues = null)
{
- $q = $this->_em->getConnection()->createQueryBuilder()
+ $q = $this->getSlaveConnection()->createQueryBuilder()
->from(MAUTIC_TABLE_PREFIX.'campaign_lead_event_log', 'o')
->leftJoin(
'o',
@@ -253,7 +254,7 @@ public function getCampaignLogCounts($campaignId, $excludeScheduled = false, $ex
}
// Exclude failed events
- $failedSq = $this->_em->getConnection()->createQueryBuilder();
+ $failedSq = $this->getSlaveConnection()->createQueryBuilder();
$failedSq->select('null')
->from(MAUTIC_TABLE_PREFIX.'campaign_lead_event_failed_log', 'fe')
->where(
@@ -338,10 +339,10 @@ public function updateLead($fromLeadId, $toLeadId)
*/
public function getChartQuery($options)
{
- $chartQuery = new ChartQuery($this->getEntityManager()->getConnection(), $options['dateFrom'], $options['dateTo']);
+ $chartQuery = new ChartQuery($this->getSlaveConnection(), $options['dateFrom'], $options['dateTo']);
// Load points for selected period
- $query = $this->_em->getConnection()->createQueryBuilder();
+ $query = $this->getSlaveConnection()->createQueryBuilder();
$query->select('ll.id, ll.date_triggered')
->from(MAUTIC_TABLE_PREFIX.'campaign_lead_event_log', 'll')
->join('ll', MAUTIC_TABLE_PREFIX.'campaign_events', 'e', 'e.id = ll.event_id');
@@ -386,6 +387,7 @@ public function getChartQuery($options)
*/
public function getScheduled($eventId, \DateTime $now, ContactLimiter $limiter)
{
+ $this->getSlaveConnection($limiter);
$q = $this->createQueryBuilder('o');
$q->select('o, e, c')
@@ -418,6 +420,7 @@ public function getScheduled($eventId, \DateTime $now, ContactLimiter $limiter)
*/
public function getScheduledByIds(array $ids)
{
+ $this->getSlaveConnection();
$q = $this->createQueryBuilder('o');
$q->select('o, e, c')
@@ -447,7 +450,7 @@ public function getScheduledCounts($campaignId, \DateTime $date, ContactLimiter
$now = clone $date;
$now->setTimezone(new \DateTimeZone('UTC'));
- $q = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $q = $this->getSlaveConnection($limiter)->createQueryBuilder();
$expr = $q->expr()->andX(
$q->expr()->eq('l.campaign_id', ':campaignId'),
@@ -486,7 +489,7 @@ public function getScheduledCounts($campaignId, \DateTime $date, ContactLimiter
*/
public function getDatesExecuted($eventId, array $contactIds)
{
- $qb = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $qb = $this->getSlaveConnection()->createQueryBuilder();
$qb->select('log.lead_id, log.date_triggered')
->from(MAUTIC_TABLE_PREFIX.'campaign_lead_event_log', 'log')
->where(
diff --git a/app/bundles/CampaignBundle/Entity/LeadRepository.php b/app/bundles/CampaignBundle/Entity/LeadRepository.php
index 123906b41b..6c8c8177d1 100644
--- a/app/bundles/CampaignBundle/Entity/LeadRepository.php
+++ b/app/bundles/CampaignBundle/Entity/LeadRepository.php
@@ -23,6 +23,7 @@
class LeadRepository extends CommonRepository
{
use ContactLimiterTrait;
+ use SlaveConnectionTrait;
/**
* Get the details of leads added to a campaign.
@@ -207,7 +208,7 @@ public function checkLeadInCampaigns($lead, $options = [])
public function getInactiveContacts($campaignId, $decisionId, $parentDecisionId, ContactLimiter $limiter)
{
// Main query
- $q = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $q = $this->getSlaveConnection($limiter)->createQueryBuilder();
$q->select('l.lead_id, l.date_added')
->from(MAUTIC_TABLE_PREFIX.'campaign_leads', 'l')
->where($q->expr()->eq('l.campaign_id', ':campaignId'))
@@ -221,7 +222,7 @@ public function getInactiveContacts($campaignId, $decisionId, $parentDecisionId,
$this->updateQueryFromContactLimiter('l', $q, $limiter);
// Limit to events that have not been executed or scheduled yet
- $eventQb = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $eventQb = $this->getSlaveConnection($limiter)->createQueryBuilder();
$eventQb->select('null')
->from(MAUTIC_TABLE_PREFIX.'campaign_lead_event_log', 'log')
->where(
@@ -237,7 +238,7 @@ public function getInactiveContacts($campaignId, $decisionId, $parentDecisionId,
if ($parentDecisionId) {
// Limit to events that have no grandparent or whose grandparent has already been executed
- $grandparentQb = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $grandparentQb = $this->getSlaveConnection($limiter)->createQueryBuilder();
$grandparentQb->select('null')
->from(MAUTIC_TABLE_PREFIX.'campaign_lead_event_log', 'grandparent_log')
->where(
@@ -279,7 +280,7 @@ public function getInactiveContactCount($campaignId, array $decisionIds, Contact
foreach ($decisionIds as $decisionId) {
// Main query
- $q = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $q = $this->getSlaveConnection()->createQueryBuilder();
$q->select('count(*)')
->from(MAUTIC_TABLE_PREFIX.'campaign_leads', 'l')
->where($q->expr()->eq('l.campaign_id', ':campaignId'))
@@ -291,7 +292,7 @@ public function getInactiveContactCount($campaignId, array $decisionIds, Contact
$this->updateQueryFromContactLimiter('l', $q, $limiter, true);
// Limit to events that have not been executed or scheduled yet
- $eventQb = $this->getEntityManager()->getConnection()->createQueryBuilder();
+ $eventQb = $this->getSlaveConnection($limiter)->createQueryBuilder();
$eventQb->select('null')
->from(MAUTIC_TABLE_PREFIX.'campaign_lead_event_log', 'log')
->where(
diff --git a/app/bundles/CampaignBundle/Entity/SlaveConnectionTrait.php b/app/bundles/CampaignBundle/Entity/SlaveConnectionTrait.php
new file mode 100644
index 0000000000..234c7e43df
--- /dev/null
+++ b/app/bundles/CampaignBundle/Entity/SlaveConnectionTrait.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * @copyright 2018 Mautic Contributors. All rights reserved
+ * @author Mautic, Inc.
+ *
+ * @link https://mautic.org
+ *
+ * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
+ */
+
+namespace Mautic\CampaignBundle\Entity;
+
+use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\Connections\MasterSlaveConnection;
+use Mautic\CampaignBundle\Executioner\ContactFinder\Limiter\ContactLimiter;
+
+/**
+ * Trait SlaveConnectionTrait.
+ */
+trait SlaveConnectionTrait
+{
+ /**
+ * Get a connection, preferring a slave connection if available and prudent.
+ *
+ * If a query is being executed with a limiter with specific contacts
+ * then this could be a real-time request being handled so we should avoid forcing a slave connection.
+ *
+ * @param ContactLimiter|null $limiter
+ *
+ * @return Connection
+ */
+ private function getSlaveConnection(ContactLimiter $limiter = null)
+ {
+ /** @var Connection $connection */
+ $connection = $this->getEntityManager()->getConnection();
+ if ($connection instanceof MasterSlaveConnection) {
+ if (
+ !$limiter
+ || !($limiter->getContactId() || $limiter->getContactIdList())
+ ) {
+ $connection->connect('slave');
+ }
+ }
+
+ return $connection;
+ }
+}
diff --git a/app/bundles/CoreBundle/Doctrine/Helper/TableSchemaHelper.php b/app/bundles/CoreBundle/Doctrine/Helper/TableSchemaHelper.php
index afbc659b49..c358f828c0 100644
--- a/app/bundles/CoreBundle/Doctrine/Helper/TableSchemaHelper.php
+++ b/app/bundles/CoreBundle/Doctrine/Helper/TableSchemaHelper.php
@@ -68,7 +68,14 @@ public function __construct(Connection $db, $prefix, ColumnSchemaHelper $columnH
$this->sm = $db->getSchemaManager();
$this->prefix = $prefix;
$this->columnHelper = $columnHelper;
- $this->schema = new Schema([], [], $this->sm->createSchemaConfig());
+ if ($db instanceof \Doctrine\DBAL\Connections\MasterSlaveConnection) {
+ $params = $db->getParams();
+ $schemaConfig = new \Doctrine\DBAL\Schema\SchemaConfig();
+ $schemaConfig->setName($params['master']['dbname']);
+ $this->schema = new Schema([], [], $schemaConfig);
+ } else {
+ $this->schema = new Schema([], [], $this->sm->createSchemaConfig());
+ }
}
/**
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment