{"action":"created","comment":{"url":"https://api.github.com/repos/apache/incubator-beam/pulls/comments/55603486","id":55603486,"diff_hunk":"@@ -0,0 +1,429 @@\n+/*\n+ * Copyright (C) 2016 Google Inc.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n+ * use this file except in compliance with the License. You may obtain a copy of\n+ * the License at\n+ *\n+ * http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n+ * License for the specific language governing permissions and limitations under\n+ * the License.\n+ */\n+package com.google.cloud.dataflow.sdk.runners.inprocess;\n+\n+import static com.google.common.base.Preconditions.checkNotNull;\n+\n+import com.google.cloud.dataflow.sdk.Pipeline;\n+import com.google.cloud.dataflow.sdk.runners.inprocess.GroupByKeyEvaluatorFactory.InProcessGroupByKeyOnly;\n+import com.google.cloud.dataflow.sdk.runners.inprocess.InMemoryWatermarkManager.FiredTimers;\n+import com.google.cloud.dataflow.sdk.runners.inprocess.InMemoryWatermarkManager.TransformWatermarks;\n+import com.google.cloud.dataflow.sdk.runners.inprocess.InProcessPipelineRunner.CommittedBundle;\n+import com.google.cloud.dataflow.sdk.runners.inprocess.InProcessPipelineRunner.PCollectionViewWriter;\n+import com.google.cloud.dataflow.sdk.runners.inprocess.InProcessPipelineRunner.UncommittedBundle;\n+import com.google.cloud.dataflow.sdk.transforms.AppliedPTransform;\n+import com.google.cloud.dataflow.sdk.transforms.PTransform;\n+import com.google.cloud.dataflow.sdk.transforms.SerializableFunction;\n+import com.google.cloud.dataflow.sdk.transforms.windowing.BoundedWindow;\n+import com.google.cloud.dataflow.sdk.transforms.windowing.Trigger;\n+import com.google.cloud.dataflow.sdk.util.ConcurrentPartitionedPriorityQueue;\n+import com.google.cloud.dataflow.sdk.util.ExecutionContext;\n+import com.google.cloud.dataflow.sdk.util.SideInputReader;\n+import com.google.cloud.dataflow.sdk.util.TimerInternals.TimerData;\n+import com.google.cloud.dataflow.sdk.util.WindowedValue;\n+import com.google.cloud.dataflow.sdk.util.WindowingStrategy;\n+import com.google.cloud.dataflow.sdk.util.common.CounterSet;\n+import com.google.cloud.dataflow.sdk.util.state.CopyOnAccessInMemoryStateInternals;\n+import com.google.cloud.dataflow.sdk.values.PCollection;\n+import com.google.cloud.dataflow.sdk.values.PCollectionView;\n+import com.google.cloud.dataflow.sdk.values.PValue;\n+import com.google.common.collect.ComparisonChain;\n+import com.google.common.collect.ImmutableList;\n+import com.google.common.collect.Iterables;\n+import com.google.common.collect.Ordering;\n+\n+import org.joda.time.Instant;\n+\n+import java.util.Collection;\n+import java.util.List;\n+import java.util.Map;\n+import java.util.concurrent.ConcurrentHashMap;\n+import java.util.concurrent.ConcurrentMap;\n+import java.util.concurrent.Executor;\n+import java.util.concurrent.Executors;\n+\n+import javax.annotation.Nullable;\n+\n+/**\n+ * The evaluation context for a specific pipeline being executed by the\n+ * {@link InProcessPipelineRunner}. Contains state shared within the execution across all\n+ * transforms.\n+ *\n+ * <p>{@link InProcessEvaluationContext} contains shared state for an execution of the\n+ * {@link InProcessPipelineRunner} that can be used while evaluating a {@link PTransform}. This\n+ * consists of views into underlying state and watermark implementations, access to read and write\n+ * {@link PCollectionView PCollectionViews}, and constructing {@link CounterSet CounterSets} and\n+ * {@link ExecutionContext ExecutionContexts}. This includes executing callbacks asynchronously when\n+ * state changes to the appropriate point (e.g. when a {@link PCollectionView} is requested and\n+ * known to be empty).\n+ *\n+ * <p>{@link InProcessEvaluationContext} also handles results by committing finalizing bundles based\n+ * on the current global state and updating the global state appropriately. This includes updating\n+ * the per-{@link StepAndKey} state, updating global watermarks, and executing any callbacks that\n+ * can be executed.\n+ */\n+class InProcessEvaluationContext {\n+  /** The step name for each {@link AppliedPTransform} in the {@link Pipeline}. */\n+  private final Map<AppliedPTransform<?, ?, ?>, String> stepNames;\n+\n+  /** The options that were used to create this {@link Pipeline}. */\n+  private final InProcessPipelineOptions options;\n+\n+  /** The current processing time and event time watermarks and timers. */\n+  private final InMemoryWatermarkManager watermarkManager;\n+\n+  private final ConcurrentPartitionedPriorityQueue<AppliedPTransform<?, ?, ?>, WatermarkCallback>\n+      pendingCallbacks;\n+\n+  // The stateInternals of the world, by applied PTransform and key.\n+  private final ConcurrentMap<StepAndKey, CopyOnAccessInMemoryStateInternals<?>>\n+      applicationStateInternals;\n+\n+  private final InProcessSideInputContainer sideInputContainer;\n+\n+  private final CounterSet mergedCounters;\n+\n+  private final Executor callbackExecutor;\n+\n+  public static InProcessEvaluationContext create(\n+      InProcessPipelineOptions options,\n+      Collection<AppliedPTransform<?, ?, ?>> rootTransforms,\n+      Map<PValue, Collection<AppliedPTransform<?, ?, ?>>> valueToConsumers,\n+      Map<AppliedPTransform<?, ?, ?>, String> stepNames,\n+      Collection<PCollectionView<?>> views) {\n+    return new InProcessEvaluationContext(\n+        options, rootTransforms, valueToConsumers, stepNames, views);\n+  }\n+\n+  private InProcessEvaluationContext(\n+      InProcessPipelineOptions options,\n+      Collection<AppliedPTransform<?, ?, ?>> rootTransforms,\n+      Map<PValue, Collection<AppliedPTransform<?, ?, ?>>> valueToConsumers,\n+      Map<AppliedPTransform<?, ?, ?>, String> stepNames,\n+      Collection<PCollectionView<?>> views) {\n+    this.options = checkNotNull(options);\n+    checkNotNull(rootTransforms);\n+    checkNotNull(valueToConsumers);\n+    checkNotNull(stepNames);\n+    checkNotNull(views);\n+    this.stepNames = stepNames;\n+\n+    this.pendingCallbacks = ConcurrentPartitionedPriorityQueue.create(new CallbackOrdering());\n+    this.watermarkManager =\n+        InMemoryWatermarkManager.create(\n+            NanosOffsetClock.create(), rootTransforms, valueToConsumers);\n+    this.sideInputContainer = InProcessSideInputContainer.create(this, views);\n+\n+    this.applicationStateInternals = new ConcurrentHashMap<>();\n+    this.mergedCounters = new CounterSet();\n+\n+    this.callbackExecutor = Executors.newCachedThreadPool();\n+  }\n+\n+  /**\n+   * Handle the provided {@link InProcessTransformResult}, produced after evaluating the provided\n+   * {@link CommittedBundle} (potentially null, if the result of a root {@link PTransform}).\n+   *\n+   * <p>The result is the output of running the transform contained in the\n+   * {@link InProcessTransformResult} on the contents of the provided bundle.\n+   *\n+   * @param completedBundle the bundle that was processed to produce the result. Potentially\n+   *                        {@code null} if the transform that produced the result is a root\n+   *                        transform\n+   * @param completedTimers the timers that were delivered to produce the {@code completedBundle},\n+   *                        or an empty iterable if no timers were delivered\n+   * @param result the result of evaluating the input bundle\n+   * @return the committed bundles contained within the handled {@code result}\n+   */\n+  public synchronized Iterable<? extends CommittedBundle<?>> handleResult(\n+      @Nullable CommittedBundle<?> completedBundle,\n+      Iterable<TimerData> completedTimers,\n+      InProcessTransformResult result) {\n+    Iterable<? extends CommittedBundle<?>> committedBundles =\n+        commitBundles(result.getOutputBundles());\n+    // Update watermarks and timers\n+    watermarkManager.updateWatermarks(\n+        completedBundle,\n+        result.getTransform(),\n+        result.getTimerUpdate().withCompletedTimers(completedTimers),\n+        committedBundles,\n+        result.getWatermarkHold());\n+    watermarksUpdated();\n+    // Update counters\n+    if (result.getCounters() != null) {\n+      mergedCounters.merge(result.getCounters());\n+    }\n+    // Update state internals\n+    CopyOnAccessInMemoryStateInternals<?> theirState = result.getState();\n+    if (theirState != null) {\n+      CopyOnAccessInMemoryStateInternals<?> committedState = theirState.commit();\n+      StepAndKey stepAndKey =\n+          StepAndKey.of(\n+              result.getTransform(), completedBundle == null ? null : completedBundle.getKey());\n+      if (!committedState.isEmpty()) {\n+        applicationStateInternals.put(stepAndKey, committedState);\n+      } else {\n+        applicationStateInternals.remove(stepAndKey);\n+      }\n+    }\n+    return committedBundles;\n+  }\n+\n+  private Iterable<? extends CommittedBundle<?>> commitBundles(\n+      Iterable<? extends UncommittedBundle<?>> bundles) {\n+    ImmutableList.Builder<CommittedBundle<?>> completed = ImmutableList.builder();\n+    for (UncommittedBundle<?> inProgress : bundles) {\n+      AppliedPTransform<?, ?, ?> producing =\n+          inProgress.getPCollection().getProducingTransformInternal();\n+      TransformWatermarks watermarks = watermarkManager.getWatermarks(producing);\n+      CommittedBundle<?> committed =\n+          inProgress.commit(watermarks.getSynchronizedProcessingOutputTime());\n+      // Empty bundles don't impact watermarks and shouldn't trigger downstream execution, so\n+      // filter them out\n+      if (!Iterables.isEmpty(committed.getElements())) {\n+        completed.add(committed);\n+      }\n+    }\n+    return completed.build();\n+  }\n+\n+  private void watermarksUpdated() {\n+    for (AppliedPTransform<?, ?, ?> transform : stepNames.keySet()) {\n+      checkCallbacks(transform);\n+    }\n+  }\n+\n+  private void checkCallbacks(AppliedPTransform<?, ?, ?> producingTransform) {\n+    TransformWatermarks watermarks = watermarkManager.getWatermarks(producingTransform);\n+    ShouldFirePredicate shouldFire = new ShouldFirePredicate(watermarks.getOutputWatermark());\n+    WatermarkCallback callback;\n+    do {\n+      callback = pendingCallbacks.pollIfSatisfies(producingTransform, shouldFire);","path":"sdk/src/main/java/com/google/cloud/dataflow/sdk/runners/inprocess/InProcessEvaluationContext.java","position":214,"original_position":214,"commit_id":"ab5c0edfe8218b3484e9511c1561b73f6239120a","original_commit_id":"ab5c0edfe8218b3484e9511c1561b73f6239120a","user":{"login":"bjchambers","id":35960,"avatar_url":"https://avatars.githubusercontent.com/u/35960?v=3","gravatar_id":"","url":"https://api.github.com/users/bjchambers","html_url":"https://github.com/bjchambers","followers_url":"https://api.github.com/users/bjchambers/followers","following_url":"https://api.github.com/users/bjchambers/following{/other_user}","gists_url":"https://api.github.com/users/bjchambers/gists{/gist_id}","starred_url":"https://api.github.com/users/bjchambers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bjchambers/subscriptions","organizations_url":"https://api.github.com/users/bjchambers/orgs","repos_url":"https://api.github.com/users/bjchambers/repos","events_url":"https://api.github.com/users/bjchambers/events{/privacy}","received_events_url":"https://api.github.com/users/bjchambers/received_events","type":"User","site_admin":false},"body":"Another option for API (not sure its better/worse):\r\n\r\npendingCallbacks.forPrefixSatisfying(fn);\r\n\r\nAnd put the loop there. Have the function return true if it did something and false if it didn't (eg., mix the loop and the predicate, so you don't need to have the excess checks for null, etc.)","created_at":"2016-03-09T22:39:27Z","updated_at":"2016-03-09T22:39:27Z","html_url":"https://github.com/apache/incubator-beam/pull/11#discussion_r55603486","pull_request_url":"https://api.github.com/repos/apache/incubator-beam/pulls/11","_links":{"self":{"href":"https://api.github.com/repos/apache/incubator-beam/pulls/comments/55603486"},"html":{"href":"https://github.com/apache/incubator-beam/pull/11#discussion_r55603486"},"pull_request":{"href":"https://api.github.com/repos/apache/incubator-beam/pulls/11"}}},"pull_request":{"url":"https://api.github.com/repos/apache/incubator-beam/pulls/11","id":61477605,"html_url":"https://github.com/apache/incubator-beam/pull/11","diff_url":"https://github.com/apache/incubator-beam/pull/11.diff","patch_url":"https://github.com/apache/incubator-beam/pull/11.patch","issue_url":"https://api.github.com/repos/apache/incubator-beam/issues/11","number":11,"state":"open","locked":false,"title":"[BEAM-22] Implement InProcessEvaluationContext","user":{"login":"tgroh","id":429866,"avatar_url":"https://avatars.githubusercontent.com/u/429866?v=3","gravatar_id":"","url":"https://api.github.com/users/tgroh","html_url":"https://github.com/tgroh","followers_url":"https://api.github.com/users/tgroh/followers","following_url":"https://api.github.com/users/tgroh/following{/other_user}","gists_url":"https://api.github.com/users/tgroh/gists{/gist_id}","starred_url":"https://api.github.com/users/tgroh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tgroh/subscriptions","organizations_url":"https://api.github.com/users/tgroh/orgs","repos_url":"https://api.github.com/users/tgroh/repos","events_url":"https://api.github.com/users/tgroh/events{/privacy}","received_events_url":"https://api.github.com/users/tgroh/received_events","type":"User","site_admin":false},"body":"This is the primary \"global state\" object for the evaluation of a\r\nPipeline using the InProcessPipelineRunner, and is responsible for\r\nproperly routing information about the state of the pipeline to\r\ntransform evaluators.\r\n\r\nRemove the InProcessEvaluationContext from the InProcessPipelineRunner\r\nclass, and implement as a class directly. Fix associated imports.\r\n\r\nSplit from the first commit in #3 ","created_at":"2016-03-02T22:22:39Z","updated_at":"2016-03-09T22:39:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9223878e22d319fc512e8f4cfe543ca82800e632","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/apache/incubator-beam/pulls/11/commits","review_comments_url":"https://api.github.com/repos/apache/incubator-beam/pulls/11/comments","review_comment_url":"https://api.github.com/repos/apache/incubator-beam/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/incubator-beam/issues/11/comments","statuses_url":"https://api.github.com/repos/apache/incubator-beam/statuses/ab5c0edfe8218b3484e9511c1561b73f6239120a","head":{"label":"tgroh:ippr_evaluation_context","ref":"ippr_evaluation_context","sha":"ab5c0edfe8218b3484e9511c1561b73f6239120a","user":{"login":"tgroh","id":429866,"avatar_url":"https://avatars.githubusercontent.com/u/429866?v=3","gravatar_id":"","url":"https://api.github.com/users/tgroh","html_url":"https://github.com/tgroh","followers_url":"https://api.github.com/users/tgroh/followers","following_url":"https://api.github.com/users/tgroh/following{/other_user}","gists_url":"https://api.github.com/users/tgroh/gists{/gist_id}","starred_url":"https://api.github.com/users/tgroh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tgroh/subscriptions","organizations_url":"https://api.github.com/users/tgroh/orgs","repos_url":"https://api.github.com/users/tgroh/repos","events_url":"https://api.github.com/users/tgroh/events{/privacy}","received_events_url":"https://api.github.com/users/tgroh/received_events","type":"User","site_admin":false},"repo":{"id":52644388,"name":"incubator-beam","full_name":"tgroh/incubator-beam","owner":{"login":"tgroh","id":429866,"avatar_url":"https://avatars.githubusercontent.com/u/429866?v=3","gravatar_id":"","url":"https://api.github.com/users/tgroh","html_url":"https://github.com/tgroh","followers_url":"https://api.github.com/users/tgroh/followers","following_url":"https://api.github.com/users/tgroh/following{/other_user}","gists_url":"https://api.github.com/users/tgroh/gists{/gist_id}","starred_url":"https://api.github.com/users/tgroh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tgroh/subscriptions","organizations_url":"https://api.github.com/users/tgroh/orgs","repos_url":"https://api.github.com/users/tgroh/repos","events_url":"https://api.github.com/users/tgroh/events{/privacy}","received_events_url":"https://api.github.com/users/tgroh/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/tgroh/incubator-beam","description":"Mirror of Apache Beam (Incubating)","fork":true,"url":"https://api.github.com/repos/tgroh/incubator-beam","forks_url":"https://api.github.com/repos/tgroh/incubator-beam/forks","keys_url":"https://api.github.com/repos/tgroh/incubator-beam/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tgroh/incubator-beam/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tgroh/incubator-beam/teams","hooks_url":"https://api.github.com/repos/tgroh/incubator-beam/hooks","issue_events_url":"https://api.github.com/repos/tgroh/incubator-beam/issues/events{/number}","events_url":"https://api.github.com/repos/tgroh/incubator-beam/events","assignees_url":"https://api.github.com/repos/tgroh/incubator-beam/assignees{/user}","branches_url":"https://api.github.com/repos/tgroh/incubator-beam/branches{/branch}","tags_url":"https://api.github.com/repos/tgroh/incubator-beam/tags","blobs_url":"https://api.github.com/repos/tgroh/incubator-beam/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tgroh/incubator-beam/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tgroh/incubator-beam/git/refs{/sha}","trees_url":"https://api.github.com/repos/tgroh/incubator-beam/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tgroh/incubator-beam/statuses/{sha}","languages_url":"https://api.github.com/repos/tgroh/incubator-beam/languages","stargazers_url":"https://api.github.com/repos/tgroh/incubator-beam/stargazers","contributors_url":"https://api.github.com/repos/tgroh/incubator-beam/contributors","subscribers_url":"https://api.github.com/repos/tgroh/incubator-beam/subscribers","subscription_url":"https://api.github.com/repos/tgroh/incubator-beam/subscription","commits_url":"https://api.github.com/repos/tgroh/incubator-beam/commits{/sha}","git_commits_url":"https://api.github.com/repos/tgroh/incubator-beam/git/commits{/sha}","comments_url":"https://api.github.com/repos/tgroh/incubator-beam/comments{/number}","issue_comment_url":"https://api.github.com/repos/tgroh/incubator-beam/issues/comments{/number}","contents_url":"https://api.github.com/repos/tgroh/incubator-beam/contents/{+path}","compare_url":"https://api.github.com/repos/tgroh/incubator-beam/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tgroh/incubator-beam/merges","archive_url":"https://api.github.com/repos/tgroh/incubator-beam/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tgroh/incubator-beam/downloads","issues_url":"https://api.github.com/repos/tgroh/incubator-beam/issues{/number}","pulls_url":"https://api.github.com/repos/tgroh/incubator-beam/pulls{/number}","milestones_url":"https://api.github.com/repos/tgroh/incubator-beam/milestones{/number}","notifications_url":"https://api.github.com/repos/tgroh/incubator-beam/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tgroh/incubator-beam/labels{/name}","releases_url":"https://api.github.com/repos/tgroh/incubator-beam/releases{/id}","deployments_url":"https://api.github.com/repos/tgroh/incubator-beam/deployments","created_at":"2016-02-27T01:43:32Z","updated_at":"2016-02-27T01:43:35Z","pushed_at":"2016-03-09T22:16:16Z","git_url":"git://github.com/tgroh/incubator-beam.git","ssh_url":"git@github.com:tgroh/incubator-beam.git","clone_url":"https://github.com/tgroh/incubator-beam.git","svn_url":"https://github.com/tgroh/incubator-beam","homepage":null,"size":11064,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"apache:master","ref":"master","sha":"f87f35b7022b36b8db04c4284df3f4b94dad7700","user":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"repo":{"id":50904245,"name":"incubator-beam","full_name":"apache/incubator-beam","owner":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/apache/incubator-beam","description":"Mirror of Apache Beam (Incubating)","fork":false,"url":"https://api.github.com/repos/apache/incubator-beam","forks_url":"https://api.github.com/repos/apache/incubator-beam/forks","keys_url":"https://api.github.com/repos/apache/incubator-beam/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/incubator-beam/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/incubator-beam/teams","hooks_url":"https://api.github.com/repos/apache/incubator-beam/hooks","issue_events_url":"https://api.github.com/repos/apache/incubator-beam/issues/events{/number}","events_url":"https://api.github.com/repos/apache/incubator-beam/events","assignees_url":"https://api.github.com/repos/apache/incubator-beam/assignees{/user}","branches_url":"https://api.github.com/repos/apache/incubator-beam/branches{/branch}","tags_url":"https://api.github.com/repos/apache/incubator-beam/tags","blobs_url":"https://api.github.com/repos/apache/incubator-beam/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/incubator-beam/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/incubator-beam/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/incubator-beam/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/incubator-beam/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/incubator-beam/languages","stargazers_url":"https://api.github.com/repos/apache/incubator-beam/stargazers","contributors_url":"https://api.github.com/repos/apache/incubator-beam/contributors","subscribers_url":"https://api.github.com/repos/apache/incubator-beam/subscribers","subscription_url":"https://api.github.com/repos/apache/incubator-beam/subscription","commits_url":"https://api.github.com/repos/apache/incubator-beam/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/incubator-beam/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/incubator-beam/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/incubator-beam/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/incubator-beam/contents/{+path}","compare_url":"https://api.github.com/repos/apache/incubator-beam/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/incubator-beam/merges","archive_url":"https://api.github.com/repos/apache/incubator-beam/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/incubator-beam/downloads","issues_url":"https://api.github.com/repos/apache/incubator-beam/issues{/number}","pulls_url":"https://api.github.com/repos/apache/incubator-beam/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/incubator-beam/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/incubator-beam/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/incubator-beam/labels{/name}","releases_url":"https://api.github.com/repos/apache/incubator-beam/releases{/id}","deployments_url":"https://api.github.com/repos/apache/incubator-beam/deployments","created_at":"2016-02-02T08:00:06Z","updated_at":"2016-03-09T13:59:24Z","pushed_at":"2016-03-09T22:16:16Z","git_url":"git://github.com/apache/incubator-beam.git","ssh_url":"git@github.com:apache/incubator-beam.git","clone_url":"https://github.com/apache/incubator-beam.git","svn_url":"https://github.com/apache/incubator-beam","homepage":null,"size":11121,"stargazers_count":58,"watchers_count":58,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":30,"mirror_url":"git://git.apache.org/incubator-beam.git","open_issues_count":9,"forks":30,"open_issues":9,"watchers":58,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/incubator-beam/pulls/11"},"html":{"href":"https://github.com/apache/incubator-beam/pull/11"},"issue":{"href":"https://api.github.com/repos/apache/incubator-beam/issues/11"},"comments":{"href":"https://api.github.com/repos/apache/incubator-beam/issues/11/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/incubator-beam/pulls/11/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/incubator-beam/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/incubator-beam/pulls/11/commits"},"statuses":{"href":"https://api.github.com/repos/apache/incubator-beam/statuses/ab5c0edfe8218b3484e9511c1561b73f6239120a"}}}}