Skip to content

Commit 5a055a2

Browse files
authored
Merge pull request #78 from ChannelFinder/recceiverid
Add recceiver id, which is used by cleanOnStart and cleanOnStop
2 parents e599f50 + cd16911 commit 5a055a2

File tree

3 files changed

+67
-48
lines changed

3 files changed

+67
-48
lines changed

server/cf.conf

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,28 @@ procs = cf
3535
# stored in /etc/channelfinderapi.conf as described in the client
3636

3737
[cf]
38-
# a space-separated list of infotags to set as CF Properties
39-
#infotags = archive foo bar blah
40-
# List environment variables that should be written as channel finder properties
38+
# cf-store application
39+
# Uncomment line below to turn on the feature to add alias records to channelfinder
40+
# alias = on
41+
# Uncomment line below to turn on the feature to add EPICS record type to channelfinder
42+
# recordType = on
43+
# Uncomment line below to turn on the feature to add description field to channelfinder
44+
# recordDesc = on
45+
# The size limit for finding channels (ie the value of the '~size' query parameter)
46+
# If not specified then the fallback is the server default
47+
# findSizeLimit = 10000
48+
# Mark all channels as 'Inactive' when processor is stopped (default: True)
49+
# cleanOnStop = True
50+
# Mark all channels as 'Inactive' when processor is started (default: True)
51+
# cleanOnStart = True
52+
# Specify an optional id for the recceiver to be used with cleanOnStart and cleanOnStop
53+
# default value is the hostname of the machine the python interpreter is started on
54+
# recceiverID = recc1
55+
# Debug output file location.
56+
# Produces no file when not defined.
57+
# debug_file_loc = /home/devuser/recsyncdata.txt
4158
#
4259
# Comma-separated list of VARIABLE:PropertyName,
4360
# specifying which environment VARIABLEs to pass on to the channel finder
4461
# and defining the corresponding PropertyName
4562
#environment_vars=ENGINEER:Engineer,EPICS_BASE:EpicsVersion,PWD:WorkingDirectory
46-
# Turn on optional alias and recordType properties
47-
#alias = on
48-
#recordType = on
49-
#recordDesc = on

server/demo.conf

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,12 @@ idkey = 42
7878
# If not specified then the fallback is the server default
7979
# findSizeLimit = 10000
8080
# Mark all channels as 'Inactive' when processor is stopped (default: True)
81-
#cleanOnStop = True
81+
# cleanOnStop = True
8282
# Mark all channels as 'Inactive' when processor is started (default: True)
83-
#cleanOnStart = True
83+
# cleanOnStart = True
84+
# Specify an optional id for the recceiver to be used with cleanOnStart and cleanOnStop
85+
# default value is the hostname of the machine the python interpreter is started on
86+
# recceiverID = recc1
8487
# Debug output file location.
8588
# Produces no file when not defined.
8689
# debug_file_loc = /home/devuser/recsyncdata.txt

server/recceiver/cfstore.py

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# -*- coding: utf-8 -*-
22

33
import logging
4+
import socket
45
_log = logging.getLogger(__name__)
56

67
from zope.interface import implementer
@@ -17,6 +18,8 @@
1718
import datetime
1819
import os
1920
import json
21+
from channelfinder import ChannelFinderClient
22+
2023

2124
# ITRANSACTION FORMAT:
2225
#
@@ -30,6 +33,8 @@
3033

3134
__all__ = ['CFProcessor']
3235

36+
RECCEIVERID_KEY = 'recceiverID'
37+
RECCEIVERID_DEFAULT = socket.gethostname()
3338

3439
@implementer(interfaces.IProcessor)
3540
class CFProcessor(service.Service):
@@ -68,11 +73,10 @@ def _startServiceWithLock(self):
6873
Using the default python cf-client. The url, username, and
6974
password are provided by the channelfinder._conf module.
7075
"""
71-
from channelfinder import ChannelFinderClient
7276
self.client = ChannelFinderClient()
7377
try:
7478
cf_props = [prop['name'] for prop in self.client.getAllProperties()]
75-
reqd_props = {'hostName', 'iocName', 'pvStatus', 'time', 'iocid'}
79+
reqd_props = {'hostName', 'iocName', 'pvStatus', 'time', 'iocid', RECCEIVERID_KEY}
7680
if (self.conf.get('alias', 'default') == 'on'):
7781
reqd_props.add('alias')
7882
if (self.conf.get('recordType', 'default') == 'on'):
@@ -224,7 +228,7 @@ def _commitWithThread(self, TR):
224228
pvInfoByName = {}
225229
for rid, (info) in pvInfo.items():
226230
if info["pvName"] in pvInfoByName:
227-
_log.warn("Commit contains multiple records with PV name: %s (%s)", pv, iocid)
231+
_log.warn("Commit contains multiple records with PV name: %s (%s)", info["pvName"], iocid)
228232
continue
229233
pvInfoByName[info["pvName"]] = info
230234
_log.debug("Add record: %s: %s", rid, info)
@@ -246,42 +250,38 @@ def _commitWithThread(self, TR):
246250
self.iocs[iocid]["channelcount"] += 1
247251
for pv in delrec:
248252
if iocid in self.channel_dict[pv]:
249-
self.channel_dict[pv].remove(iocid)
250-
if iocid in self.iocs:
251-
self.iocs[iocid]["channelcount"] -= 1
252-
if self.iocs[iocid]['channelcount'] == 0:
253-
self.iocs.pop(iocid, None)
254-
elif self.iocs[iocid]['channelcount'] < 0:
255-
_log.error("Channel count negative: %s", iocid)
256-
if len(self.channel_dict[pv]) <= 0: # case: channel has no more iocs
257-
del self.channel_dict[pv]
253+
self.remove_channel(pv, iocid)
258254
"""In case, alias exists"""
259255
if (self.conf.get('alias', 'default' == 'on')):
260256
if pv in pvInfoByName and "aliases" in pvInfoByName[pv]:
261257
for a in pvInfoByName[pv]["aliases"]:
262-
self.channel_dict[a].remove(iocid)
263-
if iocid in self.iocs:
264-
self.iocs[iocid]["channelcount"] -= 1
265-
if self.iocs[iocid]['channelcount'] == 0:
266-
self.iocs.pop(iocid, None)
267-
elif self.iocs[iocid]['channelcount'] < 0:
268-
_log.error("Channel count negative: %s", iocid)
269-
if len(self.channel_dict[a]) <= 0: # case: channel has no more iocs
270-
del self.channel_dict[a]
258+
self.remove_channel(a, iocid)
271259
poll(__updateCF__, self, pvInfoByName, delrec, hostName, iocName, iocid, owner, time)
272260
dict_to_file(self.channel_dict, self.iocs, self.conf)
273261

262+
def remove_channel(self, a, iocid):
263+
self.channel_dict[a].remove(iocid)
264+
if iocid in self.iocs:
265+
self.iocs[iocid]["channelcount"] -= 1
266+
if self.iocs[iocid]['channelcount'] == 0:
267+
self.iocs.pop(iocid, None)
268+
elif self.iocs[iocid]['channelcount'] < 0:
269+
_log.error("Channel count negative: %s", iocid)
270+
if len(self.channel_dict[a]) <= 0: # case: channel has no more iocs
271+
del self.channel_dict[a]
272+
274273
def clean_service(self):
275274
"""
276275
Marks all channels as "Inactive" until the recsync server is back up
277276
"""
278277
sleep = 1
279278
retry_limit = 5
280279
owner = self.conf.get('username', 'cfstore')
280+
recceiverid = self.conf.get(RECCEIVERID_KEY, RECCEIVERID_DEFAULT)
281281
while 1:
282282
try:
283283
_log.info("CF Clean Started")
284-
channels = self.client.findByArgs(prepareFindArgs(self.conf, [('pvStatus', 'Active')]))
284+
channels = self.client.findByArgs(prepareFindArgs(self.conf, [('pvStatus', 'Active'), (RECCEIVERID_KEY, recceiverid)]))
285285
if channels is not None:
286286
new_channels = []
287287
for ch in channels or []:
@@ -326,6 +326,7 @@ def __updateCF__(proc, pvInfoByName, delrec, hostName, iocName, iocid, owner, io
326326
channels_dict = proc.channel_dict
327327
iocs = proc.iocs
328328
conf = proc.conf
329+
recceiverid = conf.get(RECCEIVERID_KEY, RECCEIVERID_DEFAULT)
329330
new = set(pvInfoByName.keys())
330331

331332
if iocid in iocs:
@@ -354,12 +355,7 @@ def __updateCF__(proc, pvInfoByName, delrec, hostName, iocName, iocid, owner, io
354355
if len(new) == 0 or ch[u'name'] in delrec: # case: empty commit/del, remove all reference to ioc
355356
if ch[u'name'] in channels_dict:
356357
ch[u'owner'] = iocs[channels_dict[ch[u'name']][-1]]["owner"]
357-
ch[u'properties'] = __merge_property_lists([
358-
{u'name': 'hostName', u'owner': owner, u'value': iocs[channels_dict[ch[u'name']][-1]]["hostname"]},
359-
{u'name': 'iocName', u'owner': owner, u'value': iocs[channels_dict[ch[u'name']][-1]]["iocname"]},
360-
{u'name': 'iocid', u'owner': owner, u'value': channels_dict[ch[u'name']][-1]},
361-
{u'name': 'pvStatus', u'owner': owner, u'value': 'Active'},
362-
{u'name': 'time', u'owner': owner, u'value': iocTime}],
358+
ch[u'properties'] = __merge_property_lists(ch_create_properties(owner, iocTime, recceiverid, channels_dict, iocs, ch),
363359
ch[u'properties'])
364360
if (conf.get('recordType', 'default') == 'on'):
365361
ch[u'properties'] = __merge_property_lists(ch[u'properties'].append({u'name': 'recordType', u'owner': owner, u'value': iocs[channels_dict[ch[u'name']][-1]]["recordType"]}), ch[u'properties'])
@@ -371,12 +367,7 @@ def __updateCF__(proc, pvInfoByName, delrec, hostName, iocName, iocid, owner, io
371367
for a in pvInfoByName[ch[u'name']]["aliases"]:
372368
if a[u'name'] in channels_dict:
373369
a[u'owner'] = iocs[channels_dict[a[u'name']][-1]]["owner"]
374-
a[u'properties'] = __merge_property_lists([
375-
{u'name': 'hostName', u'owner': owner, u'value': iocs[channels_dict[a[u'name']][-1]]["hostname"]},
376-
{u'name': 'iocName', u'owner': owner, u'value': iocs[channels_dict[a[u'name']][-1]]["iocname"]},
377-
{u'name': 'iocid', u'owner': owner, u'value': channels_dict[a[u'name']][-1]},
378-
{u'name': 'pvStatus', u'owner': owner, u'value': 'Active'},
379-
{u'name': 'time', u'owner': owner, u'value': iocTime}],
370+
a[u'properties'] = __merge_property_lists(ch_create_properties(owner, iocTime, recceiverid, channels_dict, iocs, ch),
380371
a[u'properties'])
381372
if (conf.get('recordType', 'default') == 'on'):
382373
ch[u'properties'] = __merge_property_lists(ch[u'properties'].append({u'name': 'recordType', u'owner': owner, u'value': iocs[channels_dict[a[u'name']][-1]]["recordType"]}), ch[u'properties'])
@@ -463,11 +454,7 @@ def __updateCF__(proc, pvInfoByName, delrec, hostName, iocName, iocid, owner, io
463454
raise defer.CancelledError()
464455

465456
for pv in new:
466-
newProps = [{u'name': 'hostName', u'owner': owner, u'value': hostName},
467-
{u'name': 'iocName', u'owner': owner, u'value': iocName},
468-
{u'name': 'iocid', u'owner': owner, u'value': iocid},
469-
{u'name': 'pvStatus', u'owner': owner, u'value': "Active"},
470-
{u'name': 'time', u'owner': owner, u'value': iocTime}]
457+
newProps = create_properties(owner, iocTime, recceiverid, hostName, iocName, iocid)
471458
if (conf.get('recordType', 'default') == 'on'):
472459
newProps.append({u'name': 'recordType', u'owner': owner, u'value': pvInfoByName[pv]['recordType']})
473460
if pv in pvInfoByName and "infoProperties" in pvInfoByName[pv]:
@@ -521,6 +508,22 @@ def __updateCF__(proc, pvInfoByName, delrec, hostName, iocName, iocid, owner, io
521508
if proc.cancelled:
522509
raise defer.CancelledError()
523510

511+
def create_properties(owner, iocTime, recceiverid, hostName, iocName, iocid):
512+
return [
513+
{u'name': 'hostName', u'owner': owner, u'value': hostName},
514+
{u'name': 'iocName', u'owner': owner, u'value': iocName},
515+
{u'name': 'iocid', u'owner': owner, u'value': iocid},
516+
{u'name': 'pvStatus', u'owner': owner, u'value': 'Active'},
517+
{u'name': 'time', u'owner': owner, u'value': iocTime},
518+
{u'name': RECCEIVERID_KEY, u'owner': owner, u'value': recceiverid}]
519+
520+
def ch_create_properties(owner, iocTime, recceiverid, channels_dict, iocs, ch):
521+
return create_properties(owner, iocTime, recceiverid,
522+
iocs[channels_dict[ch[u'name']][-1]]["hostname"],
523+
iocs[channels_dict[ch[u'name']][-1]]["iocname"],
524+
channels_dict[ch[u'name']][-1])
525+
526+
524527
def __merge_property_lists(newProperties, oldProperties):
525528
"""
526529
Merges two lists of properties ensuring that there are no 2 properties with

0 commit comments

Comments
 (0)