TODO: introduce other types of paging functions - such as those that retrieve from a list of namespaces. List returns a single list object, but attempts to retrieve smaller chunks from the server to reduce the impact on the server. If the chunk attempt fails, it will load the full list instead. The
(ctx context.Context, options metav1.ListOptions)
| 74 | // server to reduce the impact on the server. If the chunk attempt fails, it will load |
| 75 | // the full list instead. The Limit field on options, if unset, will default to the page size. |
| 76 | func (p *ListPager) List(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { |
| 77 | if options.Limit == 0 { |
| 78 | options.Limit = p.PageSize |
| 79 | } |
| 80 | var list *metainternalversion.List |
| 81 | for { |
| 82 | select { |
| 83 | case <-ctx.Done(): |
| 84 | return nil, ctx.Err() |
| 85 | default: |
| 86 | } |
| 87 | |
| 88 | obj, err := p.PageFn(ctx, options) |
| 89 | if err != nil { |
| 90 | if !errors.IsResourceExpired(err) || !p.FullListIfExpired { |
| 91 | return nil, err |
| 92 | } |
| 93 | // the list expired while we were processing, fall back to a full list |
| 94 | options.Limit = 0 |
| 95 | options.Continue = "" |
| 96 | return p.PageFn(ctx, options) |
| 97 | } |
| 98 | m, err := meta.ListAccessor(obj) |
| 99 | if err != nil { |
| 100 | return nil, fmt.Errorf("returned object must be a list: %v", err) |
| 101 | } |
| 102 | |
| 103 | // exit early and return the object we got if we haven't processed any pages |
| 104 | if len(m.GetContinue()) == 0 && list == nil { |
| 105 | return obj, nil |
| 106 | } |
| 107 | |
| 108 | // initialize the list and fill its contents |
| 109 | if list == nil { |
| 110 | list = &metainternalversion.List{Items: make([]runtime.Object, 0, options.Limit+1)} |
| 111 | list.ResourceVersion = m.GetResourceVersion() |
| 112 | list.SelfLink = m.GetSelfLink() |
| 113 | } |
| 114 | if err := meta.EachListItem(obj, func(obj runtime.Object) error { |
| 115 | list.Items = append(list.Items, obj) |
| 116 | return nil |
| 117 | }); err != nil { |
| 118 | return nil, err |
| 119 | } |
| 120 | |
| 121 | // if we have no more items, return the list |
| 122 | if len(m.GetContinue()) == 0 { |
| 123 | return list, nil |
| 124 | } |
| 125 | |
| 126 | // set the next loop up |
| 127 | options.Continue = m.GetContinue() |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | // EachListItem fetches runtime.Object items using this ListPager and invokes fn on each item. If |
| 132 | // fn returns an error, processing stops and that error is returned. If fn does not return an error, |