source: trunk/FACT++/src/MessageDim.cc@ 16879

Last change on this file since 16879 was 16835, checked in by tbretz, 11 years ago
Moved the Write command back to the main thread, to ensure fast output on the console - the file access now has its own queue to decouple disk load and waiting time.
File size: 5.4 KB
Line 
1#include "MessageDim.h"
2
3#include "tools.h"
4#include "Time.h"
5
6using namespace std;
7
8// **************************************************************************
9/** @class MessageDimTX
10
11@brief Based on MessageImp, redirects log-output to a Dim service MESSAGE
12
13This is a special DimService which offers SERVER/MESSAGE to the DimNetwork
14and redirects output issued via its base-class MessageImp to the Dim
15service. The severity of the message is send as qualiy of service of
16the service message.
17
18@section Examples
19
20 - A simple and usefull example can be found in \ref log.cc and \ref logtime.cc
21
22**/
23// **************************************************************************
24
25// --------------------------------------------------------------------------
26//
27//! Constructs a DimService with the name SERVER/MESSAGE. And passes the
28//! given ostream down to the MessageImp base.
29//!
30//! @param name
31//! Name of the message server to which we want to subscribe, e.g. DRIVE
32//!
33//! @param out
34//! ostream passed to MessageImp. It is used to redirect the output to.
35//
36MessageDimTX::MessageDimTX(const std::string &name, std::ostream &out)
37 : DimDescribedService(name + "/MESSAGE", const_cast<char*>("C"),
38 "A general logging service providing a quality of service (severity)"
39 "|Message[string]:The message"),
40 MessageImp(out), fDebug(false),
41 fMsgQueue(std::bind(&MessageDimTX::UpdateService, this, placeholders::_1))
42{
43 // This is a message which will never arrive because
44 // the time to establish a client-sever connection is
45 // too short.
46 Message("MessageDimTX started.");
47}
48
49// --------------------------------------------------------------------------
50//
51//!
52//
53MessageDimTX::~MessageDimTX()
54{
55 // Everything here will never be sent by dim because the
56 // dim services have been stopped already. This is necessary,
57 // to have them available already during startup
58 Message("MessageDimTX shutting down ["+to_string(fMsgQueue.size())+"]");
59 fMsgQueue.wait();
60}
61
62void MessageDimTX::UpdateService(const tuple<Time,string,int> &data)
63{
64 setData(get<1>(data));
65 setQuality(get<2>(data));
66
67 const int rc = DimDescribedService::Update(get<0>(data));
68 if (rc==0 && fDebug)
69 Out() << " !! " << get<0>(data).GetAsStr() << " - Sending failed!" << endl;
70}
71
72// --------------------------------------------------------------------------
73//
74//! First calls MessageImp::Write to output the message tobe transmitted
75//! also to a local logging stream. Then the Dim service is updated.
76//! If sending of the message failed a message is written to the
77//! logging stream stored in MessageImp. It is intentionally not
78//! output through Update to make it look different than usual
79//! transmitted messages.
80//
81int MessageDimTX::Write(const Time &t, const string &txt, int qos)
82{
83 MessageImp::Write(t, txt, qos);
84 fMsgQueue.emplace(t, txt, qos);
85 return 1;
86}
87
88// **************************************************************************
89/** @class MessageDimRX
90
91@brief Based on MessageImp, subscribes to a MESSAGE service in the Dim network
92
93This is a special DimInfoHandler. It subscribes to a service SERVER/MESSAGE
94on the DimNetwork and redirects all received output to its base class
95MessageImp view MessageImp::Write. the quality of service received with
96each service update is passed as severity.
97
98@section Examples
99
100 - A simple and usefull example can be found in \ref log.cc and \ref logtime.cc
101
102 @todo Maybe it is not a good idea that MessageImp is a base class,
103 maybe it should be a reference given in the constructor
104
105**/
106// **************************************************************************
107
108// --------------------------------------------------------------------------
109//
110//! Setup a DimStamedInfo service subscription for SERVER/MESSAGE
111//!
112//! @param name
113//! the name of the SERVER
114//!
115//! @param imp
116//! A reference to MessageImo to which messages will be redirected
117//
118MessageDimRX::MessageDimRX(const std::string &name, MessageImp &imp)
119: fMinLogLevel(0), fConnected(false), fMsg(imp),
120fDimMessage((name+"/MESSAGE").c_str(), (void*)NULL, 0, this)
121{
122}
123
124// --------------------------------------------------------------------------
125//
126//! If the server has been disconnected write a simple log-message.
127//! Skip all received messages which have a severity smaller than
128//! fMinLogLevel. Write any other message with MessageImp::Write.
129//
130void MessageDimRX::infoHandler()
131{
132 if (getInfo()!=&fDimMessage)
133 return;
134
135 const string name = fDimMessage.getName();
136 const string server = name.substr(0, name.find_first_of('/'));
137
138 fConnected = fDimMessage.getSize()!=0;
139
140 // The server is diconnected. Do nothing
141 if (!fConnected)
142 {
143 // We cannot print this message because it is produced by
144 // every server which doesn't have the MESSAGE service, too.
145 //fMsg.Message(server+": Disconnected.");
146 return;
147 }
148
149 // skip all messages with a severity smaller than the minimum log level
150 if (fDimMessage.getQuality()<fMinLogLevel)
151 return;
152
153 const string msg = server+": "+fDimMessage.getString();
154
155 // Make sure getTimestamp is called _before_ getTimestampMillisecs
156 // Must be in exactly this order!
157 const int tsec = fDimMessage.getTimestamp();
158 const int tms = fDimMessage.getTimestampMillisecs();
159
160 // Write the received message to the output
161 fMsg.Write(Time(tsec, tms*1000), msg, fDimMessage.getQuality());
162}
Note: See TracBrowser for help on using the repository browser.