我正在编写监控指定远程机器的监控工具。
它将检索机器是否已启动,IIS是否在那里运行以及更多参数
每隔3分钟就可以监控机器上/下状态。
每隔约1分钟就可以监控IIS状态
如果其中一些参数发生了变化,它会记录更改(DistinctUntilChanged
),如果它保持不变,它就不会做任何事情。
我为机器状态创建了一个observable,为IIS状态创建了一个observable。
显然,如果机器停机,则无需监控任何其他远程参数(无需拨打GetIisState
)。
所以,我尝试使用SkipUntil
和TakeUntil
- 尝试在机器关闭时暂停IisObservable
。
但它并没有像我希望的那样工作。
这是我的机器状态可观察:
machineStateObservable = Observable.Interval(TimeSpan.FromSeconds(180))
.StartWith(-1)
.Select(async it => new {Order = it, State = await GetMachineStateAsync(machine)})
.Switch()
.Do(it =>
{
if (it.Order == -1) // write initial state 1st time
{
var state = it.State ? "up" : "down";
var msg = $"{machine.Name}: Machine initial state: {state}";
Log.Info(msg);
}
})
.Select(it => it.State);
machineStateObservable
.DistinctUntilChanged()
.Buffer(2, 1).Where(it => it.Count == 2)
.Subscribe(it => Log.Info($"{machine.Name}: MachineState got changed from {it[0]} to: {it[1]}")
, ex => Log.Error(ex, "Unhandled exception!"));
如果IisObservable
表明计算机已关闭,我应如何定义GetIisState
它不会发出通知(因此不会调用machineStateObservable
)?
更新
这是我在@Enigmativity的帮助下找到的解决方案:
IisStateObservable = MachineStateObservable
.Select(state => state
? Observable.Interval(TimeSpan.FromSeconds(2)).StartWith(0)
.SelectMany(it => Readings.GetServiceStateAsync())
: Observable.Never<string>())
.Switch()
.Publish();
答案 0 :(得分:1)
这里是创建一个observable的基本模式,只有当另一个observable产生true
而不是产生false
时才会发出。
void Main()
{
var states = new Subject<bool>();
IObservable<int> query =
states
.Select(state => state
? Observable.FromAsync(() => GetStatusAsync())
: Observable.Never<int>())
.Switch();
}
public async Task<int> GetStatusAsync()
{
return await Task.Factory.StartNew(() => 42);
}
这里的代码我建议定期调用。
void Main()
{
var states = new Subject<bool>();
IObservable<int> query =
(
from n in Observable.Interval(TimeSpan.FromMinutes(1.0))
from ms in Observable.FromAsync(() => GetMachineStateAsync())
select ms
? Observable.FromAsync(() => GetStatusAsync())
: Observable.Never<int>()
).Switch();
}
public async Task<int> GetStatusAsync()
{
return await Task.Factory.StartNew(() => 42);
}
public async Task<bool> GetMachineStateAsync()
{
return await Task.Factory.StartNew(() => true);
}
或者,根据您建议的答案。
void Main()
{
var states = new Subject<bool>();
IObservable<int> query =
states
.Select(state => state
? Observable
.Interval(TimeSpan.FromSeconds(2.0))
.StartWith(-1L)
.SelectMany(n =>
Observable.FromAsync(() => GetStatusAsync()))
: Observable.Never<int>())
.Switch();
}
public async Task<int> GetStatusAsync()
{
return await Task.Factory.StartNew(() => 42);
}