Open jml opened 8 years ago
Sorry for the terrible response latency :(
I think this makes sense. I think I'd still like an escape hatch for creating metric names that would work when defining top level metrics:
{-# NOINLINE c #-}
let c = unsafeRegisterIO $ do
name <- toMetricName "my_counter"
counter (Info name "An example metric")
or something like
{-# NOINLINE c #-}
let c = unsafeRegisterIO $ toInfo "my_counter" "An example metric" >>= counter
Would it be possible to make IO an instance of MonadError MetricNameError IO
? I think that this would just work out of the box with your proposal then.
If we can come up with a safer API that doesn't make the existing use cases much more verbose I'd be fine breaking backwards compatibility with a corresponding version bump.
Sorry for the terrible response latency :(
No worries at all.
I'd still like an escape hatch for creating metric names that would work when defining top level metrics
Yeah, I can see why that'd be nice. I've made a similar change to another library I work on and we're currently writing unsafeMakeName "literal_name"
a fair amount.
I'll think about it & get back to you.
Would it be possible to make IO an instance of MonadError MetricNameError IO?
Possible, yes. Probably inadvisable. Because we don't own MonadError
or IO
, that would be an orphan instance, which would trigger an orphan instance warning, which is there for a reason.
If we can come up with a safer API that doesn't make the existing use cases much more verbose I'd be fine breaking backwards compatibility with a corresponding version bump.
Great, thanks. I'll go away & think about it (although I've switched focus to other projects so it will be some time before I come back to this).
I also filed https://ghc.haskell.org/trac/ghc/ticket/13028#ticket about this, which describes what I think would be the best solution--to be able to write IsString
instances that do validation.
I'd still like an escape hatch for creating metric names that would work when defining top level metrics
These days I'm thinking this escape hatch is really a quasiquoter so you can do the checking at compile time rather than runtime.
I started doing this as part of #7 but the scope creep & compatibility changes got a bit too much so I thought I'd file a ticket to get an opinion before I wasted too much time.
Currently, validation of metric names doesn't actually happen (although there is a
checkInfo
function) and validation of label names happens at vector construction, but causes the program to error out, which is not ideal in library code, because it robs the caller of the ability to make a decision about how to handle errors.A good way of implementing this is to have dedicated newtypes that encode validity, e.g.
Here, the
MetricName
type and theformatMetricName
andtoMetricName
functions would be exported but not theMetricName
constructor. This guarantees that any value with theMetricName
type has a valid metric name.(Apologies if this is obvious to you, but since roundtrips are moderately expensive I thought it better to over-communicate.)
Anyway, this works for metric names but not so well for label names because the existing type class more or less assumes that the names of labels have the same type as the values of labels.
I have a bunch of half-formed ideas about what to do about that, but pretty much everything would rather seriously break backwards compatibility.
Thoughts?