Unfortunately, I can't use a side input, because I need to use the result
as an input to a DatastoreV1.Read object. This is a PTransform rather than
DoFn, so there is no place for a side input.
But you did give me the hint I needed to get something that is close
enough. It's a bit dirty, but it's what I'll have to use until something
better comes along.
public interface MyOptions extends PipelineOptions,
DataflowPipelineOptions {
@Description("ignore")
@Default.Integer(0)
ValueProvider<Integer> getIgnored();
void setIgnored(ValueProvider<Integer> value);
}
ValueProvider<DateTime> now =
NestedValueProvider.of(options.getIgnored(), ignored ->
DateTime.now(DateTimeZone.UTC));
The fact that options.getIgnored() is not static means that the value of
now can't be either. Each time I call now.get(), the value will be
re-evaluated. This isn't quite what I wanted, (I was hoping for a single
evaluation), but it will work well enough for my situation.
On Thu, May 3, 2018 at 6:01 PM, Eugene Kirpichov <[email protected]>
wrote:
> There is no way to achieve this using ValueProvider. Its value is either
> fixed at construction time (StaticValueProvider), or completely dynamic
> (evaluated every time you call .get()).
> You'll need to implement this using a side input. E.g. take a look at
> implementation of BigQueryIO, how it generates unique job id tokens -
> https://github.com/apache/beam/blob/bf94e36f67a8bc5d24c795e40697ad
> 2504c8594c/sdks/java/io/google-cloud-platform/src/
> main/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryIO.java#L756
>
> On Thu, May 3, 2018 at 5:42 PM Frank Yellin <[email protected]> wrote:
>
>> [Sorry, I accidentally hit send before I had finished typing . .]
>>
>> Is there any way to achieve what I'm looking for? Or is this just beyond
>> the scope of ValueProvider and templates?
>>
>>
>>
>> On Thu, May 3, 2018 at 5:36 PM, Frank Yellin <[email protected]> wrote:
>>
>>> I'm attempting to create a dataflow template, and within the template
>>> have a variable
>>> ValueProvider<DateTime> now
>>> such that now is the time the dataflow is started, note the time that
>>> the template was created.
>>>
>>> My first attempt was
>>> ValueProvider<DateTime> now = StaticValueProvider.of(
>>> DateTime.now(DateTimeZone.UTC));
>>>
>>> My second attempt was
>>>
>>> public interface MyOptions extends PipelineOptions,
>>> DataflowPipelineOptions {
>>> @Description("Now")
>>> @Default.InstanceFactory(GetNow.class)
>>> ValueProvider<DateTime> getNow();
>>> void setNow(ValueProvider<DateTime> value);
>>> }
>>>
>>> static class GetNow implements DefaultValueFactory<DateTime> {
>>> @Override
>>> public DateTime create(PipelineOptions options) {
>>> return DateTime.now(DateTimeZone.UTC);
>>> }
>>> }
>>>
>>> ValueProvider<DateTime> now = options.getNow()
>>>
>>> My final attempt was:
>>>
>>> ValueProvider<SerializableFunction<Void, DateTime>> nowFn =
>>> StaticValueProvider.of(x -> DateTime.now(DateTimeZone.UTC));
>>>
>>> ValueProvider<DateTime> now = NestedValueProvider.of(nowFn, x ->
>>> x.apply(null));
>>>
>>>
>>>
>>> In every case, it was clear that "now" was being set to
>>> template-creation time rather than actual runtime.
>>>
>>> I note that the documentation talks about a RuntimeValueProvider, but
>>> there is no user-visible constructor for this.
>>>
>>>
>>>
>>>
>>