Agreed. Best practices would be of great help. 

I guess your solution of a 'singleton' AdwordsServices would work.  Is the 
following what you had in mind:

- The only time we need AdwordsServices is to create the service objects. 
The service objects can be created at any time during the long lived 
process.
- We create only one global copy of the AdwordsServices object.
- The first time access to an account is needed, we use the global 
AdwordsServices (in a thread safe way) to create all the service objects we 
will need for the whole duration of the process.
- We cache the service objects instead of AdwordsServices at the account 
level, and hence no need to use AdwordsServices again.

Oliver


On Wednesday, October 10, 2012 5:00:38 PM UTC+1, j.e.frank wrote:
>
> My read was the same as yours: AdWordsServices doesn't retain the session. 
>  We have thousands of accounts so I don't want to have one per account if 
> it's a "heavyweight" object as indicated in the migration guide.  So that's 
> why I came up with idea of a wrapper object that will ensure thread safety.
>
> But I think this back-and-forth you and I are having is indicative of the 
> need for some additional examples or documentation of best practices, so 
> that each person doesn't have to puzzle it out and invent a solution.
>
> On Wednesday, October 10, 2012 7:30:13 AM UTC-4, Oliver wrote:
>>
>> I need to correct myself.  AdwordsServices itself does not hold a 
>> reference to the session. It's the actual service objects generated from 
>> AdwordsServices that do. e.g.
>>
>> CampaignServiceInterface campaignService = adWordsServices.get(session, 
>> CampaignServiceInterface.class);
>>
>>
>> But AdwordsServices is not thread safe, so caching it at the account 
>> level instead of the appliaction (multiple accounts) level will make things 
>> easier.
>>
>> Oliver
>>
>>
>> On Wednesday, October 10, 2012 11:35:54 AM UTC+1, Oliver wrote:
>>>
>>> Here is what I think:
>>>
>>> The AdwordsServices object holds a reference to the AdwordsSession 
>>> object.  Since AdwordsSession is linked to one account ID only, you need to 
>>> be very careful not to use AdwordsServices across accounts without 
>>> switching the session.
>>>
>>> What we do is create and cache a copy of AdwordsServices and 
>>> AdwordsSession for each account. The objects are re-used for all calls on 
>>> an account.  We're careful not to use multithreads when accessing the 
>>> Service API for an account (AdwordsServices).  Using multi-threads when 
>>> downloading reports is fine.
>>>
>>> Refreshtoken:  my understanding is that the client libraries will take 
>>> care of automatically refreshing the OAuth2 token if needed (however, I 
>>> have not tested this yet).  So, in theory, all you need to do is persist 
>>> the refresh token and keep using it until the end user revokes access. 
>>>
>>> If anyone has better ideas than the above please let us know.
>>>
>>> Oliver
>>>
>>>
>>>
>>> Tuesday, October 9, 2012 7:28:45 PM UTC+1, j.e.frank wrote:
>>>>
>>>> I had seen that post, which is what prompted me to post my own.  I am 
>>>> trying to better understand how multiple threads should/can share objects. 
>>>>  I don't want to go the route of "each call creates its own set of 
>>>> objects", if there's a more efficient way to do things.
>>>>
>>>> As an example, consider the AdWordsServices class, which is new (to 
>>>> me).  The migration guide says "The AdWordsServices object is fairly 
>>>> heavyweight and should be instantiated once and reused as much as 
>>>> possible."  It is not thread-safe, but it doesn't retain any state.  My 
>>>> conclusion is that if I make a singleton AdWordsServices object for use 
>>>> throughout my code, as long as I make sure no two threads are calling 
>>>> adWordsServices.get at the same time, that should be more efficient than 
>>>> creating a new one every time I need to make an AdWords API call.  In 
>>>> order 
>>>> to achieve thread safety, I will probably wrap the AdWordsServices object 
>>>> inside my own singleton object, with a synchronized "get" method that 
>>>> passes through to the wrapped AdWordsServices object.  That's an example 
>>>> of 
>>>> a best practice that I'm looking for.
>>>>
>>>> As for the OAuth2 credential, I have managed to create a valid one from 
>>>> a saved refresh token, by building the credential and then calling 
>>>> credential.refreshToken().  I'm still trying to figure out whether I need 
>>>> to do this refresh step or if it would happen automatically, and also 
>>>> whether calling refreshToken() is going to invalidate any 
>>>> AdWordsSession(s) 
>>>> that are currently using the credential before it got refreshed.  I'm 
>>>> going 
>>>> to write some tests, and once I understand the credentials, tokens, and 
>>>> AdWordsSessions better, I will be able to come up with a coding strategy 
>>>> that fits my use case (long-lived services, all with the "same" login). 
>>>>  But if there are examples already that match my use case, it will be a 
>>>> big 
>>>> time-saver and also make it more likely that I don't misunderstand how 
>>>> things work, or come up with a flawed solution.
>>>>
>>>> On Tuesday, October 9, 2012 1:42:49 PM UTC-4, Oliver wrote:
>>>>>
>>>>> You will need to persist the refresh token and account ID so your 
>>>>> services can resume on their own in case of a restart.  You can ceate 
>>>>> valid 
>>>>> AdwordsSession and AdwordsServices on the fly if you have these two 
>>>>> fields.
>>>>>
>>>>> Also, this might be of help:
>>>>>
>>>>> https://groups.google.com/forum/?fromgroups=#!topic/adwords-api/zf0slvrjkMs
>>>>>
>>>>> Oliver
>>>>>
>>>>> On Tuesday, October 9, 2012 5:08:03 PM UTC+1, j.e.frank wrote:
>>>>>>
>>>>>> I am trying to migrate to v201209 from v201109.  I have several 
>>>>>> long-lived services that use the AdWords API on behalf of my MCC 
>>>>>> account, 
>>>>>> for example to run reports, to get ad details, and so forth.  I'm trying 
>>>>>> to 
>>>>>> understand how I should be using the new session/service objects, such 
>>>>>> that 
>>>>>> more than one thing can be happening at once, but that I don't create a 
>>>>>> new 
>>>>>> session or service object when I don't need to, and also that I use my 
>>>>>> OAuth2 tokens appropriately (refresh if necessary but not every time I 
>>>>>> need 
>>>>>> to make a call).  I've seen several pieces of example code, but they are 
>>>>>> self-contained so they always get a new session, new service object, 
>>>>>> refresh the OAuth token, etc. Are there any examples more suitable for 
>>>>>> long-running services that will be invoked from time to time?
>>>>>
>>>>>

-- 
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
Also find us on our blog and discussion group:
http://adwordsapi.blogspot.com
http://groups.google.com/group/adwords-api
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~

You received this message because you are subscribed to the Google
Groups "AdWords API Forum" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/adwords-api?hl=en

Reply via email to