Skip to content

Commit 4176025

Browse files
committed
Conflicts resolved with rel-v7r1
2 parents 83e4d8a + a61a752 commit 4176025

File tree

8 files changed

+66
-11
lines changed

8 files changed

+66
-11
lines changed

release.notes

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,18 @@ NEW: (#4910) --runslow option on unit tests to allow faster local tests
137137
NEW: (#4938) added a helloworld test for the (yet to be implemented) cloud testing in certification
138138
CHANGE: (#4968) Change the defaults for tests (to MySQL 8 and ES 7)
139139

140+
[v7r1p36]
141+
142+
*DMS
143+
FIX: (#5080) SQLAlchemy 1.4 support for FTS3DB
144+
FIX: (#5054) Submit FTS3 jobs with lowercase checksum
145+
146+
*RMS
147+
FIX: (#5080) SQLAlchemy 1.4 support for ReqDB
148+
149+
*Resources
150+
FIX: (#5077) Host.py - Fix for the case where no subprocess32 module found
151+
140152
[v7r1p35]
141153

142154
FIX: Fixes from v7r0p52
@@ -740,6 +752,11 @@ FIX: (#4551) align ProxyDB test to current changes
740752
NEW: (#4289) Document how to run integration tests in docker
741753
NEW: (#4551) add DNProperties description to Registry/Users subsection
742754

755+
[v7r0p53]
756+
757+
*Interface
758+
FIX: (#5069) parseArguments strip arguments correctly
759+
743760
[v7r0p52]
744761

745762
*Core

src/DIRAC/Core/Utilities/MySQL.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@
167167
__RCSID__ = "$Id$"
168168

169169
MAXCONNECTRETRY = 10
170+
RETRY_SLEEP_DURATION = 5
170171

171172

172173
def _checkFields(inFields, inValues):
@@ -254,7 +255,7 @@ def get(self, dbName, retries=10):
254255
return self.__getWithRetry(dbName, retries, retries)
255256

256257
def __getWithRetry(self, dbName, totalRetries, retriesLeft):
257-
sleepTime = 5 * (totalRetries - retriesLeft)
258+
sleepTime = RETRY_SLEEP_DURATION * (totalRetries - retriesLeft)
258259
if sleepTime > 0:
259260
time.sleep(sleepTime)
260261
try:

src/DIRAC/DataManagementSystem/Client/FTS3Job.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,15 @@ def _constructTransferJob(self, pinTime, allLFNs, target_spacetoken, protocols=N
383383
transfers.append(stageTrans)
384384

385385
trans_metadata = {'desc': 'Transfer %s' % ftsFileID, 'fileID': ftsFileID}
386+
387+
# because of an xroot bug (https://github.com/xrootd/xrootd/issues/1433)
388+
# the checksum needs to be lowercase. It does not impact the other
389+
# protocol, so it's fine to put it here.
390+
# I only add it in this transfer and not the "staging" one above because it
391+
# impacts only root -> root transfers
386392
trans = fts3.new_transfer(sourceSURL,
387393
targetSURL,
388-
checksum='ADLER32:%s' % ftsFile.checksum,
394+
checksum='ADLER32:%s' % ftsFile.checksum.lower(),
389395
filesize=ftsFile.size,
390396
metadata=trans_metadata,
391397
activity=self.activity)

src/DIRAC/DataManagementSystem/DB/FTS3DB.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,18 @@
140140
)
141141

142142

143+
# About synchronize_session:
144+
# The FTS3DB class uses SQLAlchemy in a mixed mode:
145+
# both the ORM and the Core style.
146+
# Up to 1.3, the `session.execute` statements had no ORM functionality,
147+
# meaning that the session cache were not updated when using `update` or `delete`
148+
# Although it could be an issue, it was not really one in our case, since we always close
149+
# the session
150+
# As of 1.4, `session.execute` supports ORM functionality, and thus needs more info to know
151+
# how to manage `update` or `delete`. Hense the `synchronize_session` option.
152+
# We set it to `False` simply because we do not rely on the session cache.
153+
# Please see https://github.com/sqlalchemy/sqlalchemy/discussions/6159 for detailed discussion
154+
143155
########################################################################
144156
class FTS3DB(object):
145157
"""
@@ -312,6 +324,7 @@ def getActiveJobs(self, limit=20, lastMonitor=None, jobAssignmentTag="Assigned")
312324
.where(FTS3Job.jobID.in_(jobIds)
313325
)
314326
.values({'assignment': jobAssignmentTag})
327+
.execution_options(synchronize_session=False) # see comment about synchronize_session
315328
)
316329

317330
session.commit()
@@ -384,7 +397,8 @@ def updateFileStatus(self, fileStatusDict, ftsGUID=None):
384397
updateQuery = update(FTS3File)\
385398
.where(and_(*whereConditions)
386399
)\
387-
.values(updateDict)
400+
.values(updateDict)\
401+
.execution_options(synchronize_session=False) # see comment about synchronize_session
388402

389403
session.execute(updateQuery)
390404

@@ -435,6 +449,7 @@ def updateJobStatus(self, jobStatusDict):
435449
)
436450
)
437451
.values(updateDict)
452+
.execution_options(synchronize_session=False) # see comment about synchronize_session
438453
)
439454
session.commit()
440455

@@ -480,7 +495,8 @@ def cancelNonExistingJob(self, operationID, ftsGUID):
480495
.where(and_(FTS3File.operationID == FTS3Job.operationID,
481496
FTS3File.ftsGUID == FTS3Job.ftsGUID,
482497
FTS3Job.operationID == operationID,
483-
FTS3Job.ftsGUID == ftsGUID))
498+
FTS3Job.ftsGUID == ftsGUID))\
499+
.execution_options(synchronize_session=False) # see comment about synchronize_session
484500

485501
session.execute(updStmt)
486502
session.commit()
@@ -541,6 +557,7 @@ def getNonFinishedOperations(self, limit=20, operationAssignmentTag="Assigned"):
541557
.where(FTS3Operation.operationID.in_(operationIDs)
542558
)
543559
.values({'assignment': operationAssignmentTag})
560+
.execution_options(synchronize_session=False) # see comment about synchronize_session
544561
)
545562

546563
session.commit()
@@ -588,7 +605,9 @@ def kickStuckOperations(self, limit=20, kickDelay=2):
588605
'INTERVAL %d HOUR' %
589606
kickDelay)))) .values(
590607
{
591-
'assignment': None}))
608+
'assignment': None})
609+
.execution_options(synchronize_session=False) # see comment about synchronize_session
610+
)
592611
rowCount = result.rowcount
593612

594613
session.commit()
@@ -636,7 +655,9 @@ def kickStuckJobs(self, limit=20, kickDelay=2):
636655
'INTERVAL %d HOUR' %
637656
kickDelay)))) .values(
638657
{
639-
'assignment': None}))
658+
'assignment': None})
659+
.execution_options(synchronize_session=False) # see comment about synchronize_session
660+
)
640661
rowCount = result.rowcount
641662

642663
session.commit()
@@ -677,7 +698,8 @@ def deleteFinalOperations(self, limit=20, deleteDelay=180):
677698
rowCount = 0
678699
if opIDs:
679700
result = session.execute(delete(FTS3Operation)
680-
.where(FTS3Operation.operationID.in_(opIDs)))
701+
.where(FTS3Operation.operationID.in_(opIDs))
702+
.execution_options(synchronize_session=False))
681703
rowCount = result.rowcount
682704

683705
session.commit()

src/DIRAC/Interfaces/API/Dirac.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
def parseArguments(args):
7474
argList = []
7575
for arg in args:
76-
argList += arg.split(',')
76+
argList += [a.strip() for a in arg.split(',') if a.strip()]
7777
return argList
7878

7979

src/DIRAC/RequestManagementSystem/DB/RequestDB.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,8 @@ def cancelRequest(self, requestID):
204204
.where(Request.RequestID == requestID)
205205
.values({Request._Status: 'Canceled',
206206
Request._LastUpdate: datetime.datetime.utcnow()
207-
.strftime(Request._datetimeFormat)}))
207+
.strftime(Request._datetimeFormat)})
208+
.execution_options(synchronize_session=False)) # See FTS3DB for synchronize_session
208209
session.commit()
209210

210211
# No row was changed

src/DIRAC/Resources/Computing/BatchSystems/Host.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
import glob
2222
import shutil
2323
import signal
24-
import subprocess32 as subprocess
24+
try:
25+
import subprocess32 as subprocess
26+
except ImportError:
27+
import subprocess
2528
import stat
2629
import json
2730
import multiprocessing

tests/Integration/Core/Test_MySQLDB.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import time
1111
import pytest
1212

13+
import DIRAC
1314
from DIRAC import gLogger, gConfig
1415
from DIRAC.Core.Utilities import Time
1516
from DIRAC.Core.Utilities.MySQL import MySQL
@@ -108,9 +109,13 @@ def genVal2():
108109
('mysql', 'Dirac', 'Dirac', 'AccountingDB', 3306, True),
109110
('fake', 'fake', 'fake', 'FakeDB', 0000, False),
110111
])
111-
def test_connection(host, user, password, dbName, port, expected):
112+
def test_connection(host, user, password, dbName, port, expected, monkeypatch):
112113
""" Try to connect to a DB
113114
"""
115+
# Avoid having many retries which sleep for long durations
116+
monkeypatch.setattr(DIRAC.Core.Utilities.MySQL, "MAXCONNECTRETRY", 1)
117+
monkeypatch.setattr(DIRAC.Core.Utilities.MySQL, "RETRY_SLEEP_DURATION", 0.5)
118+
114119
mysqlDB = getDB(host, user, password, dbName, port)
115120
result = mysqlDB._connect()
116121
assert result['OK'] is expected

0 commit comments

Comments
 (0)